📄 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 + -