Jump to content

File:HarmonicDriveAni.gif

Page contents not supported in other languages.
This is a file from the Wikimedia Commons
From Wikipedia, the free encyclopedia
    Original file (700 × 700 pixels, file size: 2.36 MB, MIME type: image/gif, looped, 100 frames, 3.0 s)

    Summary

    Description
    English: Harmonic-Drive Animation (strain wave gear (SWG)). (Colors in the drawing correspond to the Cross section File:Harmonic drive cross Legend.svg.)
    Ncircular_spline = 42 (blue); Nflex_spline= 42-2 = 40 (red); Ratio = 40/(42-40) = 20
    Deutsch: Harmonic-Drive Animation (Spannungswellengetriebe, Wellgetriebe oder Gleitkeilgetriebe). (Die Farbkodierung entspricht der Schnittzeichnung File:Harmonic drive cross Legend.svg.)
    zInnenverzahnung = 42 (blue); zFlexspline= 42-2 = 40 (red); i = 40/(42-40) = 20
    Date
    Source Own work
    Author Jahobr
    GIF development
    InfoField
     This diagram was created with MATLAB by Jahobr.
    Source code
    InfoField

    MATLAB code

    function HarmonicDriveAni()
    % source code for drawing a HarmonicDrive
    % this is by no means a "simulation". It is a hack job that produces a gif
    %
    % 2016-12-05 Jahobr (reworked 2017-09-16)
     
     
    nTeethOutGear =  42;
    nTeethFlex = nTeethOutGear-2;
    modul = 0.1; % modul
     
    colEdge = [0   0   0  ]; % Edge color
    colFlex = [1   0.2 0.2]; % FlexSpline color
    colWave = [0.1 0.7 0.1]; % WaveGen color
    colGear = [0.2 0.2 1  ]; % static OuterGear color
     
    nFrames = 100;
    frameAngles = linspace(0,-pi,nFrames+1); % rotate clockwise
    frameAngles = frameAngles(1:end-1); % delete redundant frame
     
    [pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
     
    figHandle = figure(15674454);
    clf
    axesHandle = axes;
    hold(axesHandle,'on')
    axis equal
    xlim([-3 3])
    ylim([-3 3])
    set(figHandle, 'Units','pixel');
    set(figHandle, 'position',[1 1 700 700]); % [x y width height] 
    set(axesHandle, 'position',[-0.05 -0.05 1.1 1.1]); % stretch axis bigger as figure, easy way to get rid of ticks [x y width height] 
    set(figHandle,'GraphicsSmoothing','on') % requires at least version 2014b
     
    for iFrame = 1:nFrames
        
        angleWaveGen = frameAngles(iFrame);
        angleFlexTeeth = angleWaveGen*(nTeethFlex-nTeethOutGear)/nTeethFlex; %  angle of the flexspline
        
        cla(axesHandle);
        
        %% %%%%%%%%    draw OuterGear (static)   %%%%%%%%
        %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        effectiveDiameter = modul*nTeethOutGear;
        toothTipDiameter = effectiveDiameter-1.4*modul;
        toothBottomDiameter = effectiveDiameter+1.6*modul;
        
        angleBetweenTeeth = 2*pi/nTeethOutGear; % angle between 2 teeth
        angleOffPoints = (0:angleBetweenTeeth/8:(2*pi));
        
        %% outerEdge
        maxDiameter = toothBottomDiameter*1.2; % definition of outer line
        maxXY = samplesEllipse(maxDiameter,maxDiameter,500);
        patch(maxXY(:,1),maxXY(:,2),colGear,'EdgeColor',colEdge,'LineWidth',0.5) % full outer disc
        
        %% inner teeth
        radiusOffPoints = angleOffPoints; % init
        
        radiusOffPoints(1:8:end) = toothBottomDiameter/2; % middle bottom
        radiusOffPoints(2:8:end) = toothBottomDiameter/2; % left bottom
        radiusOffPoints(3:8:end) = effectiveDiameter/2; % rising edge
        radiusOffPoints(4:8:end) = toothTipDiameter/2; % right top
        radiusOffPoints(5:8:end) = toothTipDiameter/2; % middle top
        radiusOffPoints(6:8:end) = toothTipDiameter/2; % left top
        radiusOffPoints(7:8:end) = effectiveDiameter/2; % falling edge
        radiusOffPoints(8:8:end) = toothBottomDiameter/2; % right bottom
        
        [X,Y] = pol2cart(angleOffPoints,radiusOffPoints);
        
        patch(X,Y,[1 1 1],'EdgeColor',colEdge,'LineWidth',0.5) % overlay white area for inner teeth
        
        
        %% %%%%%%%%%     draw Flexspline        %%%%%%%%%
        %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        % % deform estimation based on tooth distance (using the circumferences); could be automated!
        % U1 = 42*pi % Circumference of OuterGear
        % U1 =
        %   131.9469
        %
        % U2 = pi*sqrt(2*((42/2)^2+(0.9022*42/2)^2))  * 42/40 % Circumference of Flexspline * 42/40
        % U2 =
        %   131.9435
        deform = 0.9022;
        
        deformedDiameter = effectiveDiameter*deform; % scale down, but teeth must still have the same distance
        
        rootEffectiveDia = effectiveDiameter-1.6*modul; % fixed offset
        rootDeformedDia  = deformedDiameter-1.6*modul;  % fixed offset
        
        topEffectiveDia = effectiveDiameter+1.4*modul; % fixed offset
        topDeformedDia  = deformedDiameter+1.4*modul;  % fixed offset
        
        % % an equidistant sampled ellipse is needed, to keep the tooth distance constant all the way around
        offsetOnCircumference = (-angleWaveGen+angleFlexTeeth)/2/pi; % compensation + own_rotation  ,  normalization to "circumference"
        equiEffeXY = equidistantSamplesEllipse(effectiveDiameter,deformedDiameter,nTeethFlex*8, offsetOnCircumference); % points on effective diameter
        equiRootXY = equidistantSamplesEllipse(rootEffectiveDia, rootDeformedDia, nTeethFlex*8, offsetOnCircumference); % points with inwards offset
        equiOutXY  = equidistantSamplesEllipse(topEffectiveDia,  topDeformedDia,  nTeethFlex*8, offsetOnCircumference); % points with outwards offset
        
        toothXY = equiEffeXY; % intit
        
        toothXY(1:8:end,:) = equiOutXY(1:8:end,:); % middle top        I######I
        toothXY(2:8:end,:) = equiOutXY(2:8:end,:); % left top          I######+
        % toothXY(3:8:end) init did it                                 I####/
        toothXY(4:8:end,:) = equiRootXY(4:8:end,:); % right bottom     I##+
        toothXY(5:8:end,:) = equiRootXY(5:8:end,:); % middle bottom    I##I
        toothXY(6:8:end,:) = equiRootXY(6:8:end,:); % left bottom      I##+
        % toothXY(7:8:end) init did it                                 I####\
        toothXY(8:8:end,:) = equiOutXY(8:8:end,:); % right top         I######+
        
        [toothXY] = rotateCordiantes(toothXY,angleWaveGen);
        
        patch(toothXY(:,1),toothXY(:,2),colFlex,'EdgeColor',colEdge,'LineWidth',0.5) %draw flexspline with teeth
        
        
        %% hole
        holeEffectiveDia = effectiveDiameter-5*modul; % fixed inwards offset
        holeDeformedDia  = deformedDiameter-5*modul;  % fixed inwards offset
        
        holePathXY = samplesEllipse(holeEffectiveDia,holeDeformedDia,500);
        holePathXY = rotateCordiantes(holePathXY,angleWaveGen);
        patch(holePathXY(:,1),holePathXY(:,2),[1 1 1],'EdgeColor',colEdge,'LineWidth',0.5) % draw hole of deformed ring
        
        
        %% %%%%%%%%%   draw wave generator      %%%%%%%%%
        %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        waveEffectiveDia = holeEffectiveDia; % touch flex spline
        waveDeformedDia  = holeDeformedDia-5*modul; % extra air gap to spline, to make it more obvious
        
        wavePathXY = samplesEllipse(waveEffectiveDia,waveDeformedDia,500);
        [wavePathXY] = rotateCordiantes(wavePathXY,angleWaveGen);
        patch(wavePathXY(:,1),wavePathXY(:,2),colWave,'EdgeColor',colEdge,'LineWidth',0.5) % draw wave generator
        
        %% central shaft
        shaftPathXY = samplesEllipse(effectiveDiameter/2.5,effectiveDiameter/2.5,500);
        plot(axesHandle,shaftPathXY(:,1),shaftPathXY(:,2),'LineWidth',0.8,'color',colEdge); % draw central shaft outline
        
        
        %% %%%%%%%%%   save animation     %%%%%%%%%
        %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        drawnow;
        
        f = getframe(figHandle);
        if iFrame == 1 % create colormap
            [im,map] = rgb2ind(f.cdata,32,'nodither'); % 32 colors % create color map %% THE FIRST FRAME MUST INCLUDE ALL COLORES !!!
            % FIX WHITE, rgb2ind sets white to [0.9961    0.9961    0.9961], which is annoying
            [~,wIndex] = max(sum(map,2)); % find "white"
            map(wIndex,:) = 1; % make it truly white
            im(1,1,1,nFrames) = 0; % allocate
            
            if ~isempty(which('plot2svg'))
                plot2svg(fullfile(pathstr, [fname '_Frame1.svg']),figHandle) % by Juerg Schwizer
            else
                disp('plot2svg.m not available; see http://www.zhinst.com/blogs/schwizer/');
            end
        end
        
        imtemp = rgb2ind(f.cdata,map,'nodither');
        im(:,:,1,iFrame) = imtemp;
        
    end
    imwrite(im,map,fullfile(pathstr, [fname '.gif']),'DelayTime',1/30,'LoopCount',inf) % save gif
    disp([fname '.gif  has ' num2str(numel(im)/10^6 ,4) ' Megapixels']) % Category:Animated GIF files exceeding the 50 MP limit
     
    %%% equidistantSamplesEllipse test code
    % figure(455467);clf;hold on;
    % 
    % equidistantXY = equidistantSamplesEllipse(1.5,0.5,40,0.1);
    % plot(equidistantXY(:,1),equidistantXY(:,2),'bx-')
    % 
    % 
    % equidistantXY = equidistantSamplesEllipse(2,1,40,1);
    % plot(equidistantXY(:,1),equidistantXY(:,2),'bx-')
    % 
    % equidistantXY = equidistantSamplesEllipse(3,2,40,0.5);
    % plot(equidistantXY(:,1),equidistantXY(:,2),'bx-')
    % 
    % equidistantXY = equidistantSamplesEllipse(4,3,40,0);
    % plot(equidistantXY(:,1),equidistantXY(:,2),'bx-')
    % pathXY = samplesEllipse(4,3,41);
    % plot(pathXY(1:end-1,1),pathXY(1:end-1,2),'ro-')
    % 
    % plot([4 -4]/2,[0 0],'-k')
     
     
    function equidistantXY = equidistantSamplesEllipse(diameterH,diameterV,nPoints,offset)
    % Inputs:
    %   diameterH  horizontal diameter
    %   diameterV  vertical diameter
    %   nPoints    number of resampled points
    %   offsetFraction between 0 and 1 in circumference of ellipse
     
    pathXY = samplesEllipse(diameterH,diameterV,1000); % create ellipse
    stepLengths = sqrt(sum(diff(pathXY,[],1).^2,2)); % distance between the points
    stepLengths = [0; stepLengths]; % add the starting point
    cumulativeLen = cumsum(stepLengths); % cumulative sum
    circumference = cumulativeLen(end);
    finalStepLocs = linspace(0,1, nPoints+1)+offset; % equidistant distribution
    finalStepLocs = finalStepLocs(1:end-1); % remove redundant point
    finalStepLocs = mod(finalStepLocs,1)*circumference; % unwrap and scale to circumference
    equidistantXY = interp1(cumulativeLen, pathXY, finalStepLocs);
     
     
    function pathXY = samplesEllipse(diameterH,diameterV,nPoints)
    % point of ellipse; points start on the right, counterclockwise 
    % first and last points are the same
    %
    % Inputs:
    %   diameterH  horizontal diameter
    %   diameterV  vertical diameter
    %   nPoints    number of points
     
    p = linspace(0,2*pi,nPoints)';
    pathXY = [cos(p)*diameterH/2 sin(p)*diameterV/2]; % create ellipse
     
     
    function [xy] = rotateCordiantes(xy,anglee)
    % [x1 y1; x2 y2; x3 y3; ...] coordinates to rotate
    % anglee angle of rotation in [rad]
    rotM = [cos(anglee) -sin(anglee); sin(anglee) cos(anglee)];
    xy = (rotM*xy')';
    

    Licensing

    I, the copyright holder of this work, hereby publish it under the following license:
    Creative Commons CC-Zero This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication.
    The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.

    Captions

    Add a one-line explanation of what this file represents
    depicts<\/a>"}},"text\/plain":{"en":{"":"depicts"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":751500,\"id\":\"Q751500\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P180":"strain wave gearing<\/a>"}},"text\/plain":{"en":{"P180":"strain wave gearing"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P180 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">
    copyright license<\/a>"}},"text\/plain":{"en":{"":"copyright license"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":6938433,\"id\":\"Q6938433\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P275":"Creative Commons CC0 License<\/a>"}},"text\/plain":{"en":{"P275":"Creative Commons CC0 License"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P275 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">
    inception<\/a>"}},"text\/plain":{"en":{"":"inception"}}},"{\"value\":{\"time\":\"+2016-12-05T00:00:00Z\",\"timezone\":0,\"before\":0,\"after\":0,\"precision\":11,\"calendarmodel\":\"http:\\\/\\\/www.wikidata.org\\\/entity\\\/Q1985727\"},\"type\":\"time\"}":{"text\/html":{"en":{"P571":"5 December 2016"}},"text\/plain":{"en":{"P571":"5 December 2016"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P571 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">

    5 December 2016

    source of file<\/a>"}},"text\/plain":{"en":{"":"source of file"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":66458942,\"id\":\"Q66458942\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P7482":"original creation by uploader<\/a>"}},"text\/plain":{"en":{"P7482":"original creation by uploader"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P7482 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">
    media type<\/a>"}},"text\/plain":{"en":{"":"media type"}}},"{\"value\":\"image\\\/gif\",\"type\":\"string\"}":{"text\/html":{"en":{"P1163":"image\/gif"}},"text\/plain":{"en":{"P1163":"image\/gif"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P1163 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">

    image/gif

    instance of<\/a>"}},"text\/plain":{"en":{"":"instance of"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":11201061,\"id\":\"Q11201061\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P31":"animated GIF<\/a>"}},"text\/plain":{"en":{"P31":"animated GIF"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P31 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">

    File history

    Click on a date/time to view the file as it appeared at that time.

    Date/TimeThumbnailDimensionsUserComment
    current14:20, 29 April 2023Thumbnail for version as of 14:20, 29 April 2023700 × 700 (2.36 MB)JahobrReverted to version as of 15:09, 17 November 2020 (UTC)
    07:55, 30 March 2023Thumbnail for version as of 07:55, 30 March 2023500 × 500 (734 KB)Dndnrmn1Reverted to version as of 18:48, 14 March 2017 (UTC)
    15:09, 17 November 2020Thumbnail for version as of 15:09, 17 November 2020700 × 700 (2.36 MB)JahobrReverted to version as of 20:14, 16 September 2017 (UTC)
    21:40, 9 November 2020Thumbnail for version as of 21:40, 9 November 2020700 × 700 (2.37 MB)UserTwoSixBetter color match.
    21:36, 9 November 2020Thumbnail for version as of 21:36, 9 November 2020700 × 700 (2.37 MB)UserTwoSixColor match with other image on gear page.
    20:14, 16 September 2017Thumbnail for version as of 20:14, 16 September 2017700 × 700 (2.36 MB)JahobrGraphicsSmoothing on; teeth less woblly; more pixel;
    18:48, 14 March 2017Thumbnail for version as of 18:48, 14 March 2017500 × 500 (734 KB)Jahobrcolores changed; 32 colores instead of 64; central shaft; optimized using "Jasc Animation Shop"
    05:12, 5 December 2016Thumbnail for version as of 05:12, 5 December 2016500 × 500 (1.25 MB)Jahobr{{Information |Description ={{en|1=Harmonic-Drive Animation}} {{de|1=Harmonic-Drive Animation}} |Source ={{own}} |Author =Jahobr |Date =2016-12-05 |Permission = |other_versions = }}

    The following 2 pages use this file:

    Global file usage

    The following other wikis use this file: