1 #ifdef HAVE_STDLIB_H
2 #include <stdlib.h>
3 #endif
4 #include <stdio.h>
5 #include <math.h>
6 #include <string.h>
7 #include <ctype.h>
8 #include "yagi.h"
9 
10 extern char     *optarg;
11 extern int optind, opterr;
12 #include <errno.h>
13 extern struct performance_data max, weight;
14 extern double original_percent;
15 extern double percent;
16 extern double magnitude, phase;
17 extern double Zo; /* Z0 is defined in yagi.h, Zo can be set in optimise */
18 extern double max_gain, boom_factor, diameter, best_perf;
19 extern int popsize;
20 extern int iterations, fitness_method;
21 extern double vswr;
22 extern double boom_sd, length_sd;
23 extern int K_times, K_times_max;
24 int errno;
25 double min_offset_from_peak=0.0;
26 double angular_stepsize_2=0.0;
27 
get_command_line_options(int argc,char ** argv,struct flags * flag)28 void get_command_line_options(int argc, char **argv, struct flags *flag)
29 {
30 	int c;
31 	/* Since not all complilers come with the 'getopts' functions, I've
32 	get a source of it and put it in the distribution of Yagi-Uda.
33 	To avoid conflics on unix systems, I've rename it to getoptions */
34    while((c=getoptions(argc,argv,"A:c:kwW:hvdg:Or:P:m:C:b:x:f:s:S:G:R:X:F:l:o:e:Z:p:t:T:K:")) != -1)
35    switch       (c)
36    {
37 			 case 'k': /* To keep the old start point with the GA */
38 					flag ->kflg=1;
39 					break;
40 			 case 'C':     /* Optimise by making element current the same */
41 					flag -> Cflg=atoi(optarg);
42 					break;
43 			 case 'A': /* Automatically maximise */
44 					flag->Aflg=atoi(optarg)+1000;
45 					if(flag->Aflg <-1)
46 					{
47 						fprintf(stderr,"Aflg x, where (-1<= x<= directors)\n");
48 						exit(1);
49 					}
50 					break;
51 			 case 'W':  /* weighted inprovement */
52 					flag->Wflg=atoi(optarg);
53 					if(flag->Wflg <1 || flag->Wflg>64)
54 					{
55 						fprintf(stderr,"-Wx, where x=1(gain),2() etc AND\n");
56 						exit(1);
57 					}
58 					flag->Wflg+=32768;
59 			      break;
60 			 case 'a':  /* Angular step size to use when pattern searching */
61 					flag->aflg=1;
62 					if(!isdigit( (int) *optarg) && *optarg !='.')
63 					{
64 						error_message("Non numeric data entered for option -a which requires numeric data.\n");
65 						exit(1);
66 					}
67 					angular_stepsize_2=atof(optarg);
68 					if(angular_stepsize_2 < 0.0)
69 					{
70 						error_message("The '-a' requires a posistive float, signifying the angular stepsize to use when finding sidelobes.\n");
71 						exit(1);
72 					}
73 			      break;
74 			 case 'P':  /* Get average level of pattern down */
75 					flag->Pflg=1;
76 					if(!isdigit( (int) *optarg) && *optarg !='.')
77 					{
78 						error_message("Non numeric data entered for option -P which requires numeric data.\n");
79 						exit(1);
80 					}
81 					weight.sidelobe=atof(optarg);
82 					if(weight.sidelobe < 0.0)
83 					{
84 						error_message("The '-P' requires a posistive float, signifying the weight on the sidelobe level (default=1.0).\n");
85 						exit(1);
86 					}
87 			      break;
88 			 case 'c':  /* Get average level of pattern down */
89 					if(!isdigit( (int) *optarg) && *optarg !='.')
90 					{
91 						error_message("Non numeric data entered for option -P which requires numeric data.\n");
92 						exit(1);
93 					}
94 					max.sidelobe=atof(optarg);
95 					if(max.sidelobe < 0.0)
96 					{
97 						error_message("The '-P' requires a posistive float, signifying the sidelobe level down to aim for in dB (20 is reasonable).\n");
98 						exit(1);
99 					}
100 					break;
101 			 case 'm':  /* Get minimum deviation from theta=90, to condsider a sidelobe. Higher the gain antenna, the smaller it should be set. */
102 					flag->mflg=1;
103 					if(!isdigit( (int) *optarg) && *optarg !='.')
104 					{
105 						error_message("Non numeric data entered for option -m which requires numeric data.\n");
106 						exit(1);
107 					}
108 					min_offset_from_peak=atof(optarg);
109 					if(min_offset_from_peak < 0.0|| min_offset_from_peak > 90)
110 					{
111 						error_message("The '-m' requires a posistive float, signifying the minimum offset in degrees from theta =90, to start considering a sidelobe, rather than the main beam.\n");
112 						exit(1);
113 					}
114 			      break;
115 			 case 'w':  /* wide band ant wanted - avg at low, design and upper f */
116 					flag->wflg=2; /* do at three frequencies,  2 extra ones */
117 			      break;
118 			 case 'r':   /* acceptable_resistance_error option */
119 					flag->rflg=1;
120 					if(!isdigit( (int) *optarg) && *optarg !='.')
121 					{
122 						error_message("Non numeric data entered for option -r which requires numeric data.\n");
123 						exit(1);
124 					}
125 					max.r=atof(optarg);
126 					if(max.r < 0.0)
127 					{
128 						error_message("The '-r' option setting an acceptable vswr must >=0.0\n");
129 						exit(1);
130 					}
131 			      break;
132 			 case 'x':   /* acceptable_reactance option */
133 					flag->xflg=1;
134 					if(!isdigit( (int) *optarg) && *optarg !='.')
135 					{
136 						error_message("Non numeric data entered for option -x which requires numeric data.\n");
137 						exit(1);
138 					}
139 					max.x=atof(optarg);
140 					if(max.x < 0.0)
141 					{
142 						error_message("The '-x' option setting an acceptable reactance must >=0.0\n");
143 						exit(1);
144 					}
145 			      break;
146 			 case 's':   /* acceptable_vswr option */
147 					flag->sflg=1;
148 					if(!isdigit( (int) *optarg) && *optarg !='.')
149 					{
150 						error_message("Non numeric data entered for option -s which requires numeric data.\n");
151 						exit(1);
152 					}
153 					max.swr=atof(optarg);
154 					if(max.swr < 1.0)
155 					{
156 						error_message("The '-s' option setting an acceptable vswr must >= 1.\n");
157 						exit(1);
158 					}
159 			      break;
160 			 case 'f':   /* acceptable_fb_ratio option */
161 					flag->fflg=1;
162 					if(!isdigit( (int) *optarg) && *optarg !='.')
163 					{
164 						error_message("Non numeric data entered for option -f which requires numeric data.\n");
165 						exit(1);
166 					}
167 					max.fb=atof(optarg);
168 					if(max.fb < 0.0)
169 					{
170 						error_message("The '-f' option setting an acceptable FB ratio must >=0.0\n");
171 						exit(1);
172 					}
173 			      break;
174 			 case 'F':   /* fb_ratio weight */
175 					flag->Fflg=1;
176 					if(!isdigit( (int) *optarg) && *optarg !='.')
177 					{
178 						error_message("Non numeric data entered for option -F which requires numeric data.\n");
179 						exit(1);
180 					}
181 					weight.fb=atof(optarg);
182 					if(weight.fb < 0.0)
183 					{
184 						error_message("The '-F' option setting the weight for FB ratio must >=0.0\n");
185 						exit(1);
186 					}
187 			      break;
188 			 case 'G':   /* fb_ratio weight */
189 					flag->Gflg=1;
190 					if(!isdigit( (int) *optarg) && *optarg !='.')
191 					{
192 						error_message("Non numeric data entered for option -G which requires numeric data.\n");
193 						exit(1);
194 					}
195 					weight.gain=atof(optarg);
196 					if(weight.gain < 0.0)
197 					{
198 						error_message("The '-G' option setting the weight for gain must >=0.0\n");
199 						exit(1);
200 					}
201 			      break;
202 			 case 'S':   /* weight of swr*/
203 					flag->Sflg=1;
204 					if(!isdigit( (int) *optarg) && *optarg !='.')
205 					{
206 						error_message("Non numeric data entered for option -S which requires numeric data.\n");
207 						exit(1);
208 					}
209 					weight.swr=atof(optarg);
210 					if(weight.swr < 0.0)
211 					{
212 						error_message("The '-S' option setting the weight for swr must >=0.0\n");
213 						exit(1);
214 					}
215 			      break;
216 			 case 'l':   /* percentage change in ele positions */
217 					flag->lflg=1;
218 					if(!isdigit( (int) *optarg) && *optarg !='.'&& *optarg!='-')
219 					{
220 						error_message("Non numeric data entered for option -l which requires numeric data.\n");
221 						exit(1);
222 					}
223 					original_percent=atof(optarg);
224 			      break;
225 			 case 'o':   /* optimise for gain, fb etc etc */
226 					if(!isdigit( (int) *optarg))
227 					{
228 						error_message("Non numeric data entered for option -o which requires numeric data.\n");
229 						exit(1);
230 					}
231 					flag->oflg=atoi(optarg);
232 					if(flag->oflg< 0 || flag->oflg > 128)
233 					{
234 						error_message("The '-o' option setting the parameter(s) to optimise for must be in the range 0 to 128.\n");
235 						exit(1);
236 					}
237 			      break;
238 			 case 'O':
239 					flag->Oflg=1;
240 					break;
241 			 case 'K':   /* Keep to original data, until K bad goes */
242 					flag->Kflg=1;
243 					if(!isdigit( (int) *optarg))
244 					{
245 						error_message("Non numeric data entered for option -K which requires an integer.\n");
246 						exit(1);
247 					}
248 					K_times_max=atoi(optarg);
249 					if(K_times_max < 1 )
250 					{
251 						error_message("The '-K' option setting the number of attemps to stay with hte original data after a good one found, to avoid local optimums, must be an integer > 1.\n");
252 						exit(1);
253 					}
254 			      break;
255 			 case 'b':   /* how long can boom be extended */
256 					flag->bflg=1;
257 					if(!isdigit( (int) *optarg) && *optarg !='.')
258 					{
259 						error_message("Non numeric data entered for option -b which requires numeric data.\n");
260 						exit(1);
261 					}
262 					boom_factor=atof(optarg);
263 					if(boom_factor < 0.0)
264 					{
265 						error_message("The '-b' option setting the maximum permissable change in the boom length (in %%) must be >=0.0\n");
266 						exit(1);
267 					}
268 			      break;
269 			 case 'Z':   /* Characteristic impedance */
270 					flag->Zoflg=1;
271 					if(!isdigit( (int) *optarg) && *optarg !='.')
272 					{
273 						error_message("Non numeric data entered for option -Z which requires numeric data.\n");
274 						exit(1);
275 					}
276 					Zo=atof(optarg);
277 					if(Zo <= 0.0)
278 					{
279 						error_message("The '-Z' option setting Zo must be > 0.0\n");
280 						exit(1);
281 					}
282 			      break;
283 			 case 'e':   /* type of element moved (driven, parasitic or both) */
284 					if(!isdigit( (int) *optarg) )
285 					{
286 						error_message("Non numeric data entered for option -e which requires numeric data.\n");
287 						exit(1);
288 					}
289 					flag->eflg=atoi(optarg);
290 					if(flag->eflg < 0 || flag->eflg > 1024)
291 					{
292 						error_message("The '-e' option setting the type of elements moved must be an integer between 1 and 127\n");
293 						exit(1);
294 					}
295 					if(flag->eflg==0)
296 						printf("Thats odd, you dont want to move any elements (-e0 option)\n");
297 			      break;
298 			 case 'h':
299 			      flag->hflg=1;
300 					break;
301 			 case 'v':
302 					printf("version = %f\n", version());
303 					break;
304 			 case 'd':
305 					flag->dflg=1;
306 					break;
307 			case 'g':
308 				flag->gflg=atoi(optarg);
309 				if(flag->gflg<1 || flag->gflg>64)
310 				{
311 					fprintf(stderr,"-gx, where x=1 to 64\n");
312 					exit(1);
313 				}
314 				break;
315 			case 'p':
316 				flag->pflg=1;
317 				if(!isdigit( (int) *optarg) && *optarg !='.')
318 					{
319 						error_message("Non numeric data entered for option -p which requires numeric data.\n");
320 						exit(1);
321 					}
322 				popsize=atoi(optarg);
323 				if(popsize < 2 || popsize > 10000000)
324 				{
325 						error_message("The '-p' option setting the population size of the genetric algorithm, mush be between 2 amd 1000000\n");
326 						exit(1);
327 				}
328 				break;
329 			case 't':
330 				flag->tflg=1;
331 				if(!isdigit( (int) *optarg) && *optarg !='.')
332 					{
333 						error_message("Non numeric data entered for option -t which requires numeric data.\n");
334 						exit(1);
335 					}
336 				length_sd=atof(optarg); /* SD on lengths, in mm */
337 				if(length_sd < 0 )
338 				{
339 						error_message("The '-t' option setting the standard deviation of the element lengths must be > 0\n");
340 						exit(1);
341 				}
342 				break;
343 			case 'T':
344 				flag->Tflg=1;
345 				if(!isdigit( (int) *optarg) && *optarg !='.')
346 					{
347 						error_message("Non numeric data entered for option -T which requires numeric data.\n");
348 						exit(1);
349 					}
350 				boom_sd=atof(optarg); /* SD on lengths, in mm */
351 				if(boom_sd < 0 )
352 				{
353 						error_message("The '-T' option setting the standard deviation of the boom postions must be > 0\n");
354 						exit(1);
355 				}
356 				break;
357 			 case '?':
358 			   flag->errflg++;
359 				break;
360 	 }
361 	 if(flag->Oflg)
362 	 {
363 		flag->oflg-=32768;
364 	 }
365 }
366