ConicLogSpiral

From NebarnixWiki
Revision as of 21:41, 30 April 2017 by NebarnixWikiSysop (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Problem Statement

I like antennas. I also like soviet spacecraft. In the photo of Lunakhod-1 there is a strange looking white antenna on the left side of the rover, with a black spiral. I wanted to know what this antenna was, why it was used, and maybe how hard it would be to make.

Extensive googling turned up the antenna design, a directional, extremely broadband, circularly polarized, traveling wave antenna referred to as the Conical Log Spiral Antenna. This antenna is commonly used as a feed on radio telescopes due to the extreme bandwidth and configurable directionality. This sounds amazing. I want to make one.

Biggest Problem: Though I can find many analyses of the performance of the antenna, I cannot find any calculators, generators, or other design tools. This is a tricky geometry to create, and I want to fabricate in 2D, then fold into 3D. I decided the best way to go about this was to design such a tool myself. The matlab code is listed below, though I would like to create a php version as an online realtime calculator with pdf results downloadable.

Maths

%flattened cone
clear all;
baseRadius=2;
%tipRadius = 0.1591; %starting radius, determined by the starting radius
tipRadius = baseRadius/10; %starting radius, determined by the starting radius

%Pick one code block
%Height=10;
%AspectRatio=Height/baseRadius;
%HalfAngle = pi/2-atan(AspectRatio);

%or pick the other code block
HalfAngle = degtorad(10);
AspectRatio = tan(HalfAngle);
Height = baseRadius/AspectRatio;
tipHeight = tipRadius/AspectRatio;

stripWidth = pi/2; %this is sometime called signal, and is an ANGLE in RADIANS
pitchAngleDesired = 60;

sideLength = sqrt(Height^2+baseRadius^2); %or Height/cos(HalfAngle)!
tipSideLength = sqrt(tipHeight^2+tipRadius^2); %or Height/cos(HalfAngle)!
CircumpherenceBottom = 2*pi*baseRadius;
CircumpherenceFlat = 2*pi*sideLength;
GapAngle = (CircumpherenceFlat - CircumpherenceBottom)/sideLength;
radtodeg(GapAngle)

%% Polar coordinates, 2D cone
%rho = a*e^(b*theta)
%x=r*cos(theta);
%y=r*sin(theta);

pitchAngle=atand(tand(pitchAngleDesired)*(sideLength/baseRadius));%Correction factor for the pitch angle due to conal distortion ((sideLength/baseRadius) is the scale factor)

a=tipRadius;
b=tand(90-pitchAngle);
minRadians = log(tipRadius/a)/b;
maxRadians = log(baseRadius/a)/b;
theta = minRadians:pi/100:maxRadians;
windingAngle = radtodeg(maxRadians-minRadians); %not sure what use this is
rho = a.*exp(b.*theta);
%polar(rho,theta);

%first leg, with a width
x1a=rho.*cos(theta);
y1a=rho.*sin(theta);
x1b=rho.*cos(theta+stripWidth);
y1b=rho.*sin(theta+stripWidth);

%Second leg, with a width
x2a=rho.*cos(theta+pi);
y2a=rho.*sin(theta+pi);
x2b=rho.*cos(theta+stripWidth+pi);
y2b=rho.*sin(theta+stripWidth+pi);

plot([0 0],[-tipRadius -baseRadius],x1a,y1a,'bl',x1b,y1b,'bl',x2a,y2a,'r',x2b,y2b,'r',tipRadius*cos(0:0.01:2*pi),tipRadius*sin(0:0.01:2*pi),baseRadius*cos(0:0.01:2*pi),baseRadius*sin(0:0.01:2*pi));

grid on;
%max_value = max(abs([x1a y1a ]));
axis([-baseRadius baseRadius -baseRadius baseRadius]);
pbaspect([1 1 1]);

%% 3D spiral
%rho = a*e^(b*theta)
%x=r*cos(theta);
%y=r*sin(theta);

pitchAngle=atand(tand(pitchAngleDesired)*(sideLength/baseRadius));%Correction factor for the pitch angle due to conal distortion ((sideLength/baseRadius) is the scale factor)
%pitchAngle = 60*atand(tand(45)*sideLength);

a=tipRadius;
b=tand(90-pitchAngle);
minRadians = log(tipRadius/a)/b;
maxRadians = log(baseRadius/a)/b; %this doesn't quite give us max radius?
theta = minRadians:pi/200:maxRadians;
windingAngle = radtodeg(maxRadians-minRadians); %not sure what use this is
rho = a.*exp(b.*theta);
%rho now stands for distance down ALONG cone surface, not outward

z = Height-(Height/baseRadius)*(rho);%

x1a=rho.*cos(theta);
y1a=rho.*sin(theta);
x1b=rho.*cos(theta+stripWidth);
y1b=rho.*sin(theta+stripWidth);


%Second leg, with a width
x2a=rho.*cos(theta+pi);
y2a=rho.*sin(theta++pi);

x2b=rho.*cos(theta+stripWidth+pi);
y2b=rho.*sin(theta+stripWidth+pi);
%z=Height-z;
plot3([0 0],[0 -baseRadius],[Height 0],x1a,y1a,z,'bl',x1b,y1b,z,'bl',x2a,y2a,z,'r',x2b,y2b,z,'r',tipRadius*cos(0:0.01:2*pi),tipRadius*sin(0:0.01:2*pi),Height-tipHeight * ones(numel(0:0.01:2*pi),1),baseRadius*cos(0:0.01:2*pi),baseRadius*sin(0:0.01:2*pi),zeros(numel(0:0.01:2*pi),1));
view(90,0);
%view(90,radtodeg(HalfAngle));
grid on;
max_value = max(abs([tipRadius baseRadius Height z]));
axis([-max_value max_value -max_value max_value -max_value*1.5 max_value*1.5]);
pbaspect([1 1 1]);

%% Convert to flat disc
numPtsPerRev = numel(find(theta<2*pi));
radiansPerPtOut = (2*pi-GapAngle)/numPtsPerRev;
clear idxList1a idxList1b idxList2a idxList2b;

thetaCount1a = 0;
thetaCount1b = stripWidth / (2*pi/(2*pi-GapAngle))-radiansPerPtOut;
thetaCount2a = pi / (2*pi/(2*pi-GapAngle))-radiansPerPtOut;
thetaCount2b = (stripWidth+pi) / (2*pi/(2*pi-GapAngle))-radiansPerPtOut;

for i=1:numel(theta)
    %z = Height-(Height/baseRadius)*(rho(i));%
    rhoOut(i) = rho(i)/sin(HalfAngle);
    
    thetaCount1a = thetaCount1a+radiansPerPtOut;
    thetaCount1b = thetaCount1b+radiansPerPtOut;
    thetaCount2a = thetaCount2a+radiansPerPtOut;
    thetaCount2b = thetaCount2b+radiansPerPtOut;
    
    wrapTheta=mod(theta(i),2*pi);
    if  wrapTheta == 0 %this controls the reset point
        if exist('idxList1a','var')
            idxList1a(end+1)=i;
        else
            idxList1a=i;
        end
        thetaCount1a = 0;
    end
    
    wrapTheta=mod(theta(i)+stripWidth,2*pi);
    if  wrapTheta == 0 %this controls the reset point
        if exist('idxList1b','var')
            idxList1b(end+1)=i;
        else
            idxList1b=i;
        end
        thetaCount1b = 0;
    end
    
    wrapTheta=mod(theta(i)+pi,2*pi);
    if  wrapTheta == 0 %this controls the reset point
        if exist('idxList2a','var')
            idxList2a(end+1)=i;
        else
            idxList2a=i;
        end
        thetaCount2a = 0;
    end
    
    wrapTheta=mod(theta(i)+pi+stripWidth,2*pi);
    if  wrapTheta == 0 %this controls the reset point
        if exist('idxList2b','var')
            idxList2b(end+1)=i;
        else
            idxList2b=i;
        end
        thetaCount2b = 0;
    end
    
    thetaOut1a(i) = thetaCount1a;
    thetaOut1b(i) = thetaCount1b;
    thetaOut2a(i) = thetaCount2a;
    thetaOut2b(i) = thetaCount2b;
    %rhoOut(i) = (Height-z(i))+0.0175;
    
end

xf1a=rhoOut.*cos(thetaOut1a);
yf1a=rhoOut.*sin(thetaOut1a);

xf1b=rhoOut.*cos(thetaOut1b);
yf1b=rhoOut.*sin(thetaOut1b);

xf2a=rhoOut.*cos(thetaOut2a);
yf2a=rhoOut.*sin(thetaOut2a);

xf2b=rhoOut.*cos(thetaOut2b);
yf2b=rhoOut.*sin(thetaOut2b);

%insert nans to keep matlab from connecting points
[xf1a,yf1a] = insertValues(xf1a,yf1a,idxList1a);
[xf1b,yf1b] = insertValues(xf1b,yf1b,idxList1b);
[xf2a,yf2a] = insertValues(xf2a,yf2a,idxList2a);
[xf2b,yf2b] = insertValues(xf2b,yf2b,idxList2b);

plot([tipSideLength sideLength],[0 0],[tipSideLength*cos(2*pi-GapAngle) sideLength*cos(2*pi-GapAngle)],[tipSideLength*sin(2*pi-GapAngle) sideLength*sin(2*pi-GapAngle)],tipSideLength*cos(0:0.01:2*pi-GapAngle),tipSideLength*sin(0:0.01:2*pi-GapAngle),sideLength*cos(0:0.01:2*pi-GapAngle),sideLength*sin(0:0.01:2*pi-GapAngle),xf1a,yf1a,'bl',xf1b,yf1b,'bl',xf2a,yf2a,'r',xf2b,yf2b,'r');
axis([-sideLength sideLength -sideLength sideLength]);
pbaspect([1 1 1]);

This script depends on a single function, insertValues, which inserts NaN numbers into an array, at the locations specified in a second array.

function [outputArrayX, outputArrayY]=insertValues(inputArrayX,inputArrayY,idxList)
idx2 = 1;
for i=1:numel(inputArrayX)
    
    outputArrayX(idx2) = inputArrayX(i);
    outputArrayY(idx2) = inputArrayY(i);
    
    if max(i == idxList-1)
        idx2 = idx2+1;
        outputArrayX(idx2) = NaN;
        outputArrayY(idx2) = NaN;
        
    end
    idx2 = idx2+1;
end
end