Subversion Repositories svnkaklik

Rev

Rev 645 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log

Rev 645 Rev 646
Line 2... Line 2...
2
//                        A small demo of sonar.
2
//                        A small demo of sonar.
3
// Program allow distance measuring.
3
// Program allow distance measuring.
4
// Uses cross-correlation algorithm to find echos
4
// Uses cross-correlation algorithm to find echos
5
//
5
//
6
// Author: kaklik  (kaklik@mlab.cz)
6
// Author: kaklik  (kaklik@mlab.cz)
7
//
7
//$Id:$
8
///////////////////////////////////////////////////////////////////////////////////
8
///////////////////////////////////////////////////////////////////////////////////
9
 
9
 
10
#include <stdio.h>
10
#include <stdio.h>
11
#include <stdlib.h>
11
#include <stdlib.h>
12
#include <string.h>
12
#include <string.h>
Line 19... Line 19...
19
#include <fftw3.h>
19
#include <fftw3.h>
20
 
20
 
21
#define SOUND_SPEED	340.0	// sound speed in air in metrs per second
21
#define SOUND_SPEED	340.0	// sound speed in air in metrs per second
22
#define MAX_RANGE	10.0	// maximal working radius in meters
22
#define MAX_RANGE	10.0	// maximal working radius in meters
23
#define APERTURE	0.2	// distance between microphones
23
#define APERTURE	0.2	// distance between microphones
24
#define MAP_SIZE	100
-
 
25
 
-
 
26
#define RESOLUTION	100	// resolution per map pixel
-
 
27
 
24
 
28
static char *device = "plughw:0,0";			/* playback device */
25
static char *device = "plughw:0,0";			/* playback device */
29
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;	/* sample format */
26
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;	/* sample format */
30
static unsigned int rate = 96000;			/* stream rate */
27
static unsigned int rate = 96000;			/* stream rate */
31
static unsigned int buffer_time = 2 * (MAX_RANGE / SOUND_SPEED * 1e6);		/* ring buffer length in us */
28
static unsigned int buffer_time = 2 * (MAX_RANGE / SOUND_SPEED * 1e6);		/* ring buffer length in us */
Line 204... Line 201...
204
    int err;
201
    int err;
205
    snd_pcm_hw_params_t *hwparams;
202
    snd_pcm_hw_params_t *hwparams;
206
    snd_pcm_sw_params_t *swparams;
203
    snd_pcm_sw_params_t *swparams;
207
 
204
 
208
    long int *correlationl, *correlationr;
205
    long int *correlationl, *correlationr;
-
 
206
    float *echo_map;
209
    int *L_signal, *R_signal;
207
    int *L_signal, *R_signal;
210
    short *chirp, *signal;
208
    short *chirp, *signal;
211
    float *chirp_spect, *lecho_spect, *recho_spect;
209
    float *chirp_spect, *lecho_spect, *recho_spect;
212
    float x,y;
210
    float x,y;
213
    unsigned int i,j,m,n;
211
    unsigned int i,j,m,n;
214
    unsigned int delayl[10],delayr[10];	//store delay of signifed correlation
212
    unsigned int delayl[10],delayr[10];	//store delay of signifed correlation
215
    long int l,r;  // store correlation at strict time
213
    long int l,r;  // store correlation at strict time
216
    double df;	//frequency resolution 
214
    double df;	//frequency resolution 
217
    unsigned int frequency_bins; // number of output frequency bins 
215
    unsigned int frequency_bins; // number of output frequency bins 
218
 
216
 
219
    float density_map[MAP_SIZE][MAP_SIZE];  // Array to store two dimensional image of echos
-
 
220
 
-
 
221
    double *inchirp;
217
    double *inchirp;
222
    fftw_complex *outchirp;
218
    fftw_complex *outchirp;
223
    fftw_plan fft_plan_chirp;
219
    fftw_plan fft_plan_chirp;
224
 
220
 
225
    FILE *out;
221
    FILE *out;
226
 
222
 
227
    snd_pcm_hw_params_alloca(&hwparams);
223
    snd_pcm_hw_params_alloca(&hwparams);
228
    snd_pcm_sw_params_alloca(&swparams);
224
    snd_pcm_sw_params_alloca(&swparams);
229
 
225
 
230
    printf("Simple PC sonar ver. 000000001 starting work.. \n");
226
    printf("Simple PC sonar $Rev:$ starting work.. \n");
231
 
227
 
232
//open and set playback device
228
//open and set playback device
233
    if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
229
    if ((err = snd_pcm_open(&playback_handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
234
    {
230
    {
235
        printf("Playback open error: %s\n", snd_strerror(err));
231
        printf("Playback open error: %s\n", snd_strerror(err));
Line 276... Line 272...
276
    correlationr = malloc(period_size * sizeof(long int)); //array to store correlation curve
272
    correlationr = malloc(period_size * sizeof(long int)); //array to store correlation curve
277
    L_signal = malloc(period_size * sizeof(int));
273
    L_signal = malloc(period_size * sizeof(int));
278
    R_signal = malloc(period_size * sizeof(int));
274
    R_signal = malloc(period_size * sizeof(int));
279
    chirp = calloc(2*period_size, sizeof(short));
275
    chirp = calloc(2*period_size, sizeof(short));
280
    signal = malloc(2*period_size * sizeof(short));
276
    signal = malloc(2*period_size * sizeof(short));
-
 
277
    echo_map = malloc(3*period_size * sizeof(float));   // Array to store two dimensional image of echos
281
 
278
 
282
// generate ping pattern
279
// generate ping pattern
283
    chirp_size = linear_windowed_chirp(chirp);
280
    chirp_size = linear_windowed_chirp(chirp);
284
 
281
 
285
    frequency_bins = chirp_size / 2 + 1;
282
    frequency_bins = chirp_size / 2 + 1;
Line 364... Line 361...
364
        }
361
        }
365
        correlationl[n]=abs(l);
362
        correlationl[n]=abs(l);
366
        correlationr[n]=abs(r);
363
        correlationr[n]=abs(r);
367
    }
364
    }
368
 
365
 
-
 
366
    m=0;
369
    printf("Building echo map\n");		// compute map from left and right correlation data
367
    printf("Building echo map\n");		// compute map from left and right correlation data
370
    for (i=0;i < MAP_SIZE; i++)
-
 
371
    {
-
 
372
 
-
 
373
	for (j=0;j < MAP_SIZE; j++)
368
	for (i=0;i < period_size; i++)
374
	{
369
	{
375
	  x=(float)i*RESOLUTION; y=(float)j*RESOLUTION;	 //transofm integger index of array to float with appproopirate resolution 
370
		for(j=0;j < period_size; j++)
376
 
371
		{
-
 
372
			echo_map[m]=(i*i-j*j+APERTURE*APERTURE)/(2*APERTURE);
377
	  density_map[i][j]=(float)correlationl[(int)sqrt(x*x + y*y)]*correlationr[(int)sqrt(APERTURE*APERTURE - 2*APERTURE*x + x*x + y*y)];
373
			echo_map[m+1]=sqrt(-(i-j-APERTURE)*(i+j-APERTURE)*(i-j+APERTURE)*(i+j+APERTURE))/(2*r);
-
 
374
			echo_map[m+2]=correlationl[i]*correlationr[j];
-
 
375
			m+=3;
-
 
376
		}
378
	}
377
	}
379
    }
-
 
380
 
378
 
381
 
379
 
382
    printf("Searching echos\n");
380
    printf("Searching echos\n");
383
    r=0;
381
    r=0;
384
    l=0;
382
    l=0;
Line 394... Line 392...
394
            delayr[1] = n;
392
            delayr[1] = n;
395
            r = correlationr[n];
393
            r = correlationr[n];
396
        }
394
        }
397
    }
395
    }
398
 
396
 
399
//spocitejj frekvencni spektrum pro levy kanal
397
//spocitej frekvencni spektrum pro levy kanal
400
    for(i=delayl[1]; i < delayl[1] + chirp_size; i++) inchirp[i-delayl[1]] = L_signal[i];
398
    for(i=delayl[1]; i < delayl[1] + chirp_size; i++) inchirp[i-delayl[1]] = L_signal[i];
401
    fftw_execute(fft_plan_chirp);
399
    fftw_execute(fft_plan_chirp);
402
    for(i=0; i < frequency_bins; i++) lecho_spect[i] = sqrt(outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1]);
400
    for(i=0; i < frequency_bins; i++) lecho_spect[i] = sqrt(outchirp[i][0] * outchirp[i][0] + outchirp[i][1] * outchirp[i][1]);
403
 
401
 
404
 
402
 
Line 413... Line 411...
413
    {
411
    {
414
        fprintf(out,"%2.3f %6d %6d %9ld %9ld\n",SOUND_SPEED * (float) i / rate,L_signal[i],R_signal[i],correlationl[i], correlationr[i]);
412
        fprintf(out,"%2.3f %6d %6d %9ld %9ld\n",SOUND_SPEED * (float) i / rate,L_signal[i],R_signal[i],correlationl[i], correlationr[i]);
415
    }
413
    }
416
    fclose(out);
414
    fclose(out);
417
 
415
 
-
 
416
    j=0;
418
    out=fopen("/tmp/plane_cut.txt","w"); // writes plane cut - e.g. density map to file
417
    out=fopen("/tmp/plane_cut.txt","w"); // writes plane cut - e.g. density map to file
419
    for (i=0;i < MAP_SIZE; i++)
418
    for (i=0;i < period_size; i++)
420
    {
419
    {
421
	for (j=0;j < MAP_SIZE; j++) fprintf(out,"%3.2f ", density_map);
420
	fprintf(out,"%3.2f %3.2f %3.2f\n", echo_map[j], echo_map[j+1], echo_map[j+2]);
422
	fprintf(out,"\n");
421
	j+=3;
423
    }
422
    }
424
 
423
 
425
    out=fopen("/tmp/chirp.txt","w");
424
    out=fopen("/tmp/chirp.txt","w");
426
    for (i=0; i <= (chirp_size - 1); i++)
425
    for (i=0; i <= (chirp_size - 1); i++)
427
    {
426
    {
Line 444... Line 443...
444
    free(correlationr);
443
    free(correlationr);
445
    free(L_signal);
444
    free(L_signal);
446
    free(R_signal);
445
    free(R_signal);
447
    free(chirp);
446
    free(chirp);
448
    free(signal);
447
    free(signal);
-
 
448
    free(echo_map);
449
 
449
 
450
    snd_pcm_close(playback_handle);
450
    snd_pcm_close(playback_handle);
451
    snd_pcm_close(capture_handle);
451
    snd_pcm_close(capture_handle);
452
    return 0;
452
    return 0;
453
}
453
}