⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jakes.cpp

📁 本程序仿真了随机变量的产生和多径信道情况
💻 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 + -