?? jakes.cpp
字號:
/*
**********************************************************************************
利用Jakes模型產生一個瑞利衰落信道
********************************************************************************
*/
/*
********************************************************************************
* INCLUDE FILES
********************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "channel.h"
#include "Jakes.h"
/*
*******************************************************************************
* constants and define declarations
*******************************************************************************
*/
#define PI 3.141592653589793
#define FADER_OSCI_NUM 15
#define PATH_COEF_VAR 1.0
#define MAX_MULTI_PATH_NUM 10
#define PATH_TIME_LINE_LEN 200
/*
*******************************************************************************
* local object definition
*******************************************************************************
*/
/* 存儲延時的同相分量 */
double delay_i[PATH_TIME_LINE_LEN];
/* 存儲延時的正交分量 */
double delay_q[PATH_TIME_LINE_LEN];
/* 延時數據的首地址 */
int head = 0;
/* 多徑結構 */
MultiPathSt multipath[MAX_MULTI_PATH_NUM];
/* 多徑個數 */
int path_num = 1;
/* 隨機數種子 */
struct seed path_seed = {1,1,1};
/*
********************************************************************************
初始化一個Jakes模型
********************************************************************************
*/
void SetJake(JakeSt *p_jake, int osci_num, double sample_rate, double fmax, double sigma)
{
int n;
double angle;//角度
/* 初始化各個參數 */
p_jake->osci_num = osci_num;
p_jake->sample_rate = sample_rate;
p_jake->fmax = fmax;
p_jake->sigma = sigma;
p_jake->time = 0;
p_jake->time_step = 1.0 / sample_rate;
/* 計算各個頻率 */
for (n=0; n<osci_num; n++)
{
angle = (2*PI*n - PI + (2*random_u(&path_seed) - 1)*PI) / (4 * osci_num );
p_jake->wd[n] = 2 * PI * fmax * cos(angle);
}
/* 隨機生成初始相位 */
for (n=0; n<osci_num; n++)
{
p_jake->init_i_phase[n] = 2 * PI * random_u(&path_seed);
p_jake->init_q_phase[n] = 2 * PI * random_u(&path_seed);
}
}
/*
********************************************************************************
測試一個Jakes模型
********************************************************************************
*/
void RunJake(JakeSt *p_jake, double *inph, double *quad)
{
int n;
double factor;
/* 采樣由Jakes模型生成的衰落信號 */
(*inph) = 0;
(*quad) = 0;
for (n=0; n<p_jake->osci_num; n++)
{
(*inph) += cos(p_jake->wd[n] * p_jake->time + p_jake->init_i_phase[n]);
(*quad) += sin(p_jake->wd[n] * p_jake->time + p_jake->init_q_phase[n]);
}
factor = sqrt(2.0 / p_jake->osci_num);
(*inph) *= factor;
(*quad) *= factor;
/* 累加時間到下一步 */
p_jake->time += p_jake->time_step;
}
/*
********************************************************************************
初始化一個多徑衰落信道
********************************************************************************
*/
void SetMultiPath()
{
double fc; /* 載波頻率 */
double velocity; /* 移動速度 */
double sample_rate; /* 采樣率 */
double gain[MAX_MULTI_PATH_NUM]; /* 各徑增益 */
double delay[MAX_MULTI_PATH_NUM]; /* 各徑延時 */
double fmax; /* 多普勒最大頻偏 */
double time_step; /* 采樣時間間隔 */
double power; /* 多徑功率和 */
double delay_sum; /* 總延時 */
int l;
head = 0;
/*從配置文件中讀取參數*/
read_config(&fc, &velocity, &sample_rate, &path_num, gain, delay);
/* 計算采樣間隔 */
time_step = 1.0e6 / sample_rate;
/* 計算每徑的增益和延遲 */
delay_sum = 0;
power = 0;
for (l=0; l<path_num; l++)
{
delay_sum += delay[l];
/* 設置延遲位置 */
multipath[l].pos = (int)(delay_sum/time_step + 0.5);
/* 設置增益 */
multipath[l].gain = sqrt( pow(10, gain[l]/10.0) );
power += multipath[l].gain * multipath[l].gain;
}
/* 增益歸一化 */
for (l=0; l<path_num; l++)
{
multipath[l].gain = multipath[l].gain * sqrt(0.5 * PATH_COEF_VAR) / sqrt(power);
}
/* 計算多普勒最大頻偏 */
fmax = velocity * fc / 1.08e9;
/* 對各個單徑用Jakes建立模型 */
for (l=0; l<path_num; l++)
{
SetJake(&multipath[l].jake, FADER_OSCI_NUM, sample_rate, fmax, PATH_COEF_VAR);
}
}
/*
********************************************************************************
測試一個多徑衰落信道
********************************************************************************
*/
void RunMultiPath(double inph_in, double quad_in, double *inph_out, double *quad_out)
{
int l;
int delay_pos;
double path_coef_i;
double path_coef_q;
/* 存儲延遲數據 */
head = (head - 1 + PATH_TIME_LINE_LEN) % PATH_TIME_LINE_LEN;
delay_i[head] = inph_in;
delay_q[head] = quad_in;
/* 產生輸出 */
(*inph_out) = 0;
(*quad_out) = 0;
for (l=0; l<path_num; l++)
{
/* 對每一徑進行計算 */
RunJake(&multipath[l].jake, &path_coef_i, &path_coef_q);
path_coef_i *= multipath[l].gain;
path_coef_q *= multipath[l].gain;
/* calculate the delay position */
delay_pos = multipath[l].pos;
delay_pos = (delay_pos + head) % PATH_TIME_LINE_LEN;
/* complex multiplication and accumulation */
(*inph_out) += path_coef_i * delay_i[delay_pos] - path_coef_q * delay_q[delay_pos];
(*quad_out) += path_coef_i * delay_q[delay_pos] + path_coef_q * delay_i[delay_pos];
}
}
/*
********************************************************************************
讀取多徑信道配置
********************************************************************************
*/
void read_config (double *fc, double *velocity, double *sample_rate, int *path_num,
double *gain, double *delay)
{
FILE *fp_config = NULL;
char config_note[200] = {0};
int i = 0;
//打開配置文件
if (NULL==(fp_config=fopen("config.dat","r")))
{
printf ("can't open config.dat\n");
exit (0);
}
//讀取載波頻率
fgets (config_note, 200, fp_config);
fscanf (fp_config, "%lf", fc);
fgets (config_note, 200, fp_config);
//讀取移動速度
fgets (config_note, 200, fp_config);
fscanf (fp_config, "%lf", velocity);
fgets (config_note, 200, fp_config);
//讀取采樣率)
fgets (config_note, 200, fp_config);
fscanf (fp_config, "%lf", sample_rate);
fgets (config_note, 200, fp_config);
//多徑個數
fgets (config_note, 200, fp_config);
fscanf (fp_config, "%d", path_num);
fgets (config_note, 200, fp_config);
//讀取每徑的增益和延時
for (i=0; i<*path_num; i++)
{
//讀取增益
fgets (config_note, 200, fp_config);
fscanf (fp_config, "%lf", &gain[i]);
fgets (config_note, 200, fp_config);
//讀取延時
fgets (config_note, 200, fp_config);
fscanf (fp_config, "%lf", &delay[i]);
fgets (config_note, 200, fp_config);
if (i == *path_num-1)
{
break;
}
}
fclose (fp_config);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -