# ConicLogSpiral

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

## 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;
%tipRadius = 0.1591; %starting radius, determined by the starting radius

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

%or pick the other code block
AspectRatio = tan(HalfAngle);

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)!
CircumpherenceFlat = 2*pi*sideLength;
GapAngle = (CircumpherenceFlat - CircumpherenceBottom)/sideLength;

%% 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)

b=tand(90-pitchAngle);
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);

grid on;
%max_value = max(abs([x1a y1a ]));
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);

b=tand(90-pitchAngle);
maxRadians = log(baseRadius/a)/b; %this doesn't quite give us max radius?
rho = a.*exp(b.*theta);
%rho now stands for distance down ALONG cone surface, not outward

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;
view(90,0);
grid on;
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));
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)
rhoOut(i) = rho(i)/sin(HalfAngle);

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
```