28、星历处理任务实现

\qquad 下面是HD-GR GNSS导航软件的星历处理任务实现代码:

// main_ephemeris.c -- Ephemeris processing task.

/* 
 * Copyright (C) 2005 Andrew Greenberg
 * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991).
 * See the "COPYING" file distributed with this software for more information.
 */

/* Namuru GPS receiver project
 * Original : ephemeris.c
 * Modes    : LED handling for debugging commented/replaced
 * version  : V1.0
 * date     : 21st/Dec/2006
 */

/* 
 * HD-GR GNSS receiver project
 * Modes    : Inherited the code of ephemeris.c and ephemeris.h in the Namuru 
 *            GPS receiver project V1.0 and made necessary adjustments to adapt 
 *            to the new RTOS and functions.
 * version  : V1.0
 * date     : xx/xx/2015
 */

#include <io.h>
#include <stdio.h>
#include <math.h>
#include "includes.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "main_position.h"
#include "gps_ephemeris.h"
#include "gps_almanac.h"
#include "b1i_ephemeris.h"
#include "b1i_almanac.h"

/******************************************************************************
 * Defines
 ******************************************************************************/

/******************************************************************************
 * Globals
 ******************************************************************************/

OS_FLAG_GRP* m_EphemerisChannelFlag;
OS_FLAG_GRP* m_EphemerisSubframeFlags[TOT_MAX_CHANNELS];
OS_EVENT *m_EphTabMutex = 0;

/******************************************************************************
 * Statics
 ******************************************************************************/

// None

void initialize_ephetable( void)
{
	gps_initialize_ephetable();
	b1i_initialize_ephetable();
}


/****************************************************************************
FUNCTION satpos_almanac(double time, almanac_t *p)
RETURNS  SATELLITE POSITION.

PARAMETERS
	time	-- time of week
	pSatAlm	-- satellite almanac

PURPOSE
	THIS SUBROUTINE CALCULATES THE SATELLITE POSITION BASED ON ALMANAC DATA

	R    - RADIUS OF SATELLITE AT TIME T
	SLAT - SATELLITE LATITUDE
	SLONG- SATELLITE LONGITUDE
	T    - TIME FROM START OF WEEKLY EPOCH
	ETY  - ORBITAL ECCENTRICITY
	TOA  - TIME OF APPLICABILITY FROM START OF WEEKLY EPOCH
	INC  - ORBITAL INCLINATION
	RRA  - RATE OF RIGHT ASCENSION
	SQA  - SQUARE ROOT OF SEMIMAJOR AXIS
	LAN  - LONGITUDE OF NODE AT WEEKLY EPOCH
	AOP  - ARGUMENT OF PERIGEE
	MA   - MEAN ANOMALY AT TOA

WRITTEN BY
	Clifford Kelley
****************************************************************************/

xyz_t satpos_almanac(double time, almanac_t *pSatAlm)
{
	xyz_t result;
	double ei, ea, diff, r, ta, la, aol, xp, yp, d_toa;

	// MA IS THE ANGLE FROM PERIGEE AT TOA
	d_toa = time - pSatAlm->toa;
	if (d_toa > 302400.0)
		d_toa = d_toa - 604800.0;
	else if (d_toa < -302400.0)
		d_toa = d_toa + 604800.0;
	ei = pSatAlm->ma + d_toa * pSatAlm->w;
	ea = ei;
	do {
		diff = (ei - (ea - pSatAlm->ety * sin (ea))) / (1. - pSatAlm->ety * cos (ea));
		ea = ea + diff;
	} while (fabs (diff) > 1.0e-6);
	// EA IS THE ECCENTRIC ANOMALY

	if (pSatAlm->ety != 0.0) {
		ta = atan2 (sqrt (1. - SQ (pSatAlm->ety)) * sin (ea), cos (ea) - pSatAlm->ety);
	}
	else {
		ta = ea;
	}
	// TA IS THE TRUE ANOMALY (ANGLE FROM PERIGEE)

	r = SQ (pSatAlm->sqa) * (1. - pSatAlm->ety * cos (ea));
	// R IS THE RADIUS OF SATELLITE ORBIT AT TIME T

	aol = ta + pSatAlm->aop;
	// AOL IS THE ARGUMENT OF LATITUDE

	// LA IS THE LONGITUDE OF THE ASCENDING NODE
	la = pSatAlm->lan + (pSatAlm->rra - OMEGA_E) * d_toa - pSatAlm->toa * OMEGA_E;

	xp = r * cos (aol);
	yp = r * sin (aol);
	result.x = xp * cos (la) - yp * cos (pSatAlm->inc) * sin (la);
	result.y = xp * sin (la) + yp * cos (pSatAlm->inc) * cos (la);
	result.z = yp * sin (pSatAlm->inc);
	return result;
}

/****************************************************************************
FUNCTION satfind()
RETURNS  None.

PARAMETERS None.

PURPOSE

	THIS FUNCTION DETERMINES THE SATELLITES TO SEARCH FOR
	WHEN ALMANAC DATA IS AVAILABLE

WRITTEN BY
	Clifford Kelley

*****************************************************************************/

int satfind (
	unsigned short bgps,
	int prn,
	stdtime_t gmt,
	pvt_t rec_pos,
	neu_t rec_neu,
	azel_t *pazel,
	double *pvel)
{
	if (prn < 0 || prn > 31 || !pazel) {
		return 0;
	}

	almanac_t *pSatAlm = bgps ? (&m_gps_alm[prn]):(&m_b1i_alm[prn]);
	if (!pSatAlm->update || pSatAlm->health) {
		return 0;
	}

	int gps_week;
	double jd_day, alm_time, almanac_date;

	pazel->az = 0;
	pazel->el = 0;

	jd_day = to_julian_time(gmt);
	gps_week = (int)((jd_day - 2444244.5) / 7.);
	almanac_date = pSatAlm->week * 7.0 + 2444244.5;
	if (gps_week - pSatAlm->week > 512) {
		almanac_date += 1024 * 7.0;
	}
	alm_time = (jd_day - almanac_date) * 86400.;

	// CALCULATE THE POSITION OF THE SATELLITES
	if (prn > 0 && pSatAlm->inc > 0.0) {
		xyz_t gnsspos;
		xyzt_t satpost;

		gnsspos = satpos_almanac (alm_time, &m_gps_alm[prn]);
		satpost.tb = 0;
		satpost.x = gnsspos.x;
		satpost.y = gnsspos.y;
		satpost.z = gnsspos.z;
		*pazel = satellite_azel(satpost, rec_pos, rec_neu);
		if (pvel) {
			xyz_t gpsspd;
			double range, xls, yls, zls;

			gpsspd = satpos_almanac (alm_time + 1.0, &m_gps_alm[prn]);
			gpsspd.x -= gnsspos.x;
			gpsspd.y -= gnsspos.y;
			gpsspd.z -= gnsspos.z;

			xls = rec_pos.x - gnsspos.x;
			yls = rec_pos.y - gnsspos.y;
			zls = rec_pos.z - gnsspos.z;
			range = sqrt (xls * xls + yls * yls + zls * zls);
			xls = xls / range;
			yls = yls / range;
			zls = zls / range;
			*pvel = gpsspd.x * xls + gpsspd.y * yls + gpsspd.z * zls;
		}
		return 1;
	}
	return 0;
}

/******************************************************************************
 * Stuff incoming bits from the message task into words and subframes in
 * the messages structure.
 ******************************************************************************/
void ephemeris_task(void* pdata) // input 'pdata' not used
{
	INT8U err;
	unsigned short ch;
    OS_FLAGS channels_ready;
    
    // There's no way that we're going to get a subframe before this thread
    // is first executed, so it's ok to run the flag inits here.
	m_EphemerisChannelFlag = OSFlagCreate((OS_FLAGS)0, &err);
#ifdef GNSS_ENABLE_MUTEX
	m_EphTabMutex = OSMutexCreate(EPHEM_TASK_PRIORITY, &err);
#endif

    for (ch = 0; ch < TOT_MAX_CHANNELS; ch++) {
		m_EphemerisSubframeFlags[ch] = OSFlagCreate((OS_FLAGS)0, &err);
	}
    
    while (1) {
		// Block if there are no channels_ready with bits ready. Wake up if any
		// bits from the 20 channels_ready (0xFFFFF) are set. Clear the flag on
		// wake up, with the bits saved in channels_ready_with_bits.
		channels_ready = OSFlagPend(m_EphemerisChannelFlag,
			(1 << TOT_MAX_CHANNELS) - 1,
			OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME, 
			0, &err);

		// led_turnon(LED3);
		if (m_sys_posconst & POS_CONSTELL_BDS) {
			b1i_ephemeris_task(channels_ready >> GPS_MAX_CHANNELS);
		}
		if (m_sys_posconst & POS_CONSTELL_GPS) {
			gps_ephemeris_task(channels_ready);
		}
		// led_turnoff(LED3);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值