RTK_base/task/rtk_task.c

339 lines
11 KiB
C
Raw Normal View History

2022-06-16 18:57:17 +08:00
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-06-15 fize the first version
*/
#include <rtk_task.h>
#define LOG_TAG "USER_TASK"
2022-06-22 09:23:36 +08:00
#define EVENT_FLAG(...) (1<<__VA_ARGS__)
2022-06-16 18:57:17 +08:00
2022-06-22 09:23:36 +08:00
#define EVENT_REF_RTCM_DATA_FLAG EVENT_FLAG(0)
#define EVENT_UAER_RTCM_DATA_FLAG EVENT_FLAG(1)
2022-06-16 18:57:17 +08:00
2022-06-22 09:23:36 +08:00
#define THREAD_get_user_rtcm_data_priority 10
#define THREAD_get_ref_rtcm_data_priority 10
#define thread_rtk_proces_priority 9
2022-06-16 18:57:17 +08:00
2022-06-22 09:23:36 +08:00
#define get_rtcm_user_data_stack_size DEFAULT_USER_THREAD_STACK_SIZE
2022-06-27 15:36:14 +08:00
#define get_rtcm_ref_data_stack_size DEFAULT_USER_THREAD_STACK_SIZE
2022-06-22 09:23:36 +08:00
#define rtk_proces_stack_size DEFAULT_USER_THREAD_STACK_SIZE
2022-06-16 18:57:17 +08:00
2022-06-22 09:23:36 +08:00
//rtcm_t rtcm_data;
struct rt_event uart_event;
struct rt_completion rtcm_ref_data_process_completion;
struct rt_completion rtcm_user_data_process_completion;
2022-06-16 18:57:17 +08:00
2022-06-22 09:23:36 +08:00
static struct rt_thread get_user_rtcm_data;
static char thread_user_rtcm_data_stack[get_rtcm_user_data_stack_size];
static struct rt_thread get_ref_rtcm_data;
static char thread_ref_rtcm_data_stack[get_rtcm_ref_data_stack_size];
2022-06-16 18:57:17 +08:00
2022-06-22 09:23:36 +08:00
struct rt_mutex userf_svrlock;
rtksvr_t *svr; /* rtk server struct */
//serial3 -->user serial_rtcm_buff[0][]
//serial6 -->ref serial_rtcm_buff[1][]
char buff[8000];
2022-06-22 09:23:36 +08:00
static void thread_get_ref_rtcm_data(void *parameter)
{
while (1)
{
2022-06-22 09:23:36 +08:00
//to make sure there is only one sem exist at uart,keep data from being damaged by dma transmit.
//rt thread could not get uart status when it receiving data.
//it may cross frame lost if the system runs slow.
2022-06-27 15:36:14 +08:00
if (rt_sem_take(&uart6_simpack.rx_sem, RT_WAITING_FOREVER) == RT_EOK) //need a completion sem connect to rtcm data processing thread.
2022-06-22 09:23:36 +08:00
{
if (rt_completion_wait(&rtcm_ref_data_process_completion, RT_WAITING_NO) == RT_EOK)
{
READ_SERIAL6(svr->buff[1]);
// READ_SERIAL6(buff);
svr->nb[1] = uart6_simpack.rx_num;
rt_event_send(&uart_event, EVENT_REF_RTCM_DATA_FLAG);
}
else
{
if (uart6_simpack.rx_num != 0)
{
char *drop = rt_malloc(uart6_simpack.rx_num);
if (drop == RT_NULL)
{
LOG_E("heap not enough for thread_get_ref_rtcm_data");
}
else
{
READ_SERIAL6(drop);
rt_free(drop);
}
}
}
2022-06-22 09:23:36 +08:00
}
2022-06-22 09:23:36 +08:00
}
}
static void thread_get_user_rtcm_data(void *parameter)
2022-06-16 18:57:17 +08:00
{
while (1)
{
//to make sure there is only one sem exist at uart,keep data from being damaged by dma transmit.
//rt thread could not get uart status when it receiving data.
//it may cross frame lost if the system runs slow.
2022-06-22 09:23:36 +08:00
if (rt_sem_take(&uart3_simpack.rx_sem, RT_WAITING_FOREVER) == RT_EOK) //need a completion sem connect to rtcm data processing thread.
2022-06-16 18:57:17 +08:00
{
if (rt_completion_wait(&rtcm_user_data_process_completion, RT_WAITING_NO) == RT_EOK)
{
READ_SERIAL3(svr->buff[0]);
svr->nb[0] = uart3_simpack.rx_num;
rt_event_send(&uart_event, EVENT_UAER_RTCM_DATA_FLAG);
}
else
{
if (uart3_simpack.rx_num != 0)
{
char *drop = rt_malloc(uart3_simpack.rx_num);
if (drop == RT_NULL)
{
LOG_E("heap not enough for thread_get_user_rtcm_data");
}
else
{
READ_SERIAL3(drop);
rt_free(drop);
}
}
}
2022-06-16 18:57:17 +08:00
}
}
}
2022-06-22 09:23:36 +08:00
/* global variables ----------------------------------------------------------*/
static int svrcycle = 50; /* server cycle (ms) */
static int buffsize = 4096; /* input buffer size (bytes) */
static int strfmt[] = { STRFMT_RTCM3, STRFMT_RTCM3 }; /* stream formats */
static int nmeacycle = 5000; /* nmea request cycle (ms) */
static int nmeareq = 0; /* nmea request type (0:off,1:lat/lon,2:single) */
extern prcopt_t prcopt_;
extern solopt_t solopt_;
//static obsd_t data[MAXOBS * 2]; /* 7616 B */
2022-06-22 09:23:36 +08:00
static void thread_rtk_proces(void *parameter)
2022-06-16 18:57:17 +08:00
{
2022-06-22 09:23:36 +08:00
double pos[3] = { 0.0, 0.0, 0.0 }, npos[3] = { 0.0, 0.0, 0.0 };
static double nmeapos[] = { 0, 0, 0 };
uint32_t recevd_event = 0;
2022-06-22 09:23:36 +08:00
svr = (rtksvr_t *) rt_malloc(sizeof(rtksvr_t));
if (svr == RT_NULL)
{
LOG_E("mem not enough for svr&prcopt&solopt");
}
/* STEP-1: <20><><EFBFBD><EFBFBD>RTK<54><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ */
resetsysopts(); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ */
getsysopts(NULL, NULL); /* ָ<><D6B8>ָ<EFBFBD><D6B8><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ */
/* STEP-2: <20><>ʼ<EFBFBD><CABC>RTK<54><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9B9> */
rtksvrinit(svr);
/* STEP-3: <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>NMEA<45><41>Ϣ */
/* <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>GGA<47><41>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>Ϣ, Ҳ<><D2B2><EFBFBD>Դӵ<D4B4><D3B5>㶨λ<E3B6A8>л<EFBFBD>ȡ */
pos[0] = nmeapos[0] * D2R;
pos[1] = nmeapos[1] * D2R;
pos[2] = nmeapos[2];
pos2ecef(pos, npos);
/* STEP-5: <20><>ʼRTK<54><4B><EFBFBD>߳<EFBFBD> */
rtksvrstart_mini(svr, svrcycle, buffsize, strfmt, nmeacycle, nmeareq, nmeapos, &prcopt_, &solopt_);
obs_t obs; /* 28 B */
2022-06-27 15:36:14 +08:00
2022-06-22 09:23:36 +08:00
sol_t sol = { { 0 } }; /* 199 B */
double tt;
uint32_t tick, ticknmea, tick1hz, tickreset;
uint8_t *p, *q;
int n = 0, fobs[2] = { 0 }, cycle, cputime = 0;
2022-06-22 09:23:36 +08:00
svr->state = 1;
// obs.data = data;
2022-06-22 09:23:36 +08:00
svr->tick = tickget();
ticknmea = tick1hz = svr->tick - 1000;
tickreset = svr->tick - 30000;
rt_completion_done(&rtcm_user_data_process_completion);
rt_completion_done(&rtcm_ref_data_process_completion);
2022-06-16 18:57:17 +08:00
while (1)
{
2022-06-22 09:23:36 +08:00
if (!svr->state)
{
2022-06-27 15:36:14 +08:00
rt_thread_sleep(1);
2022-06-22 09:23:36 +08:00
}
else
2022-06-16 18:57:17 +08:00
{
2022-06-22 09:23:36 +08:00
tick = tickget();
2022-06-22 09:23:36 +08:00
rt_event_recv(&uart_event, (EVENT_UAER_RTCM_DATA_FLAG | EVENT_REF_RTCM_DATA_FLAG),
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), RT_WAITING_FOREVER, &recevd_event);
if (recevd_event & EVENT_UAER_RTCM_DATA_FLAG || recevd_event & EVENT_REF_RTCM_DATA_FLAG)
2022-06-22 09:23:36 +08:00
{
if (recevd_event & EVENT_UAER_RTCM_DATA_FLAG)
{
fobs[0] = decoderaw(svr, 0);
rt_completion_done(&rtcm_user_data_process_completion);
}
if (recevd_event & EVENT_REF_RTCM_DATA_FLAG)
{
fobs[1] = decoderaw(svr, 1);
rt_completion_done(&rtcm_ref_data_process_completion);
}
2022-06-22 09:23:36 +08:00
}
else
2022-06-22 09:23:36 +08:00
{
// rt_thread_sleep(5);
2022-06-22 09:23:36 +08:00
continue;
}
uint8_t nr = 0;
uint8_t nu = 0;
2022-06-22 09:23:36 +08:00
/* <20><><EFBFBD><EFBFBD>׼վ<D7BC><D5BE><EFBFBD>ƶ<EFBFBD>վ<EFBFBD>Ĺ۲<C4B9><DBB2><EFBFBD><EFBFBD>ݺ϶<DDBA>Ϊһ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>MAXOBS*2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>Ҿ<EFBFBD><D2BE><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>? */
obs.n = 0;
for (int i = 0; i < fobs[0]; i++)
2022-06-22 09:23:36 +08:00
{
for (int j = 0; j < svr->obs[0][i].n; j++)
2022-06-22 09:23:36 +08:00
{
nu++;
}
}
for (int i = 0; i < fobs[1]; i++)
{
for (int j = 0; j < svr->obs[1][i].n; j++)
2022-06-22 09:23:36 +08:00
{
nr++;
}
}
nu = (nu > MAXOBS) ? MAXOBS : nu;
nr = (nr > MAXOBS * 2 - nu) ? (MAXOBS * 2) - nr : nr;
if (nu + nr == 0)
{
// rt_thread_mdelay(5);
continue;
}
obs.data = (obsd_t *) rt_malloc(sizeof(obsd_t) * (nu + nr));
obs.n = 0;
for (int i = 0; i < fobs[0]; i++)
{
for (int j = 0; j < svr->obs[0][i].n && obs.n < nu; j++)
2022-06-22 09:23:36 +08:00
{
obs.data[obs.n++] = svr->obs[0][i].data[j];
2022-06-22 09:23:36 +08:00
}
}
for (int i = 0; i < fobs[1]; i++)
{
for (int j = 0; j < svr->obs[1][i].n && obs.n < nu + nr; j++)
2022-06-22 09:23:36 +08:00
{
obs.data[obs.n++] = svr->obs[1][i].data[j];
2022-06-22 09:23:36 +08:00
}
}
/* rtk positioning */
// rtksvrlock(svr);
rtkpos(&svr->rtk, obs.data, obs.n, &svr->nav);
// rtksvrunlock(svr);
rt_free(obs.data);
obs.data = RT_NULL;
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч, <20><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
if (svr->rtk.sol.stat != SOLQ_NONE)
{
/* adjust current time */
tt = (int) (tickget() - tick) / 1000.0 + DTTOL;
timeset(gpst2utc(timeadd(svr->rtk.sol.time, tt)));
/* write solution */
// writesol_mini(svr, i);
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>˷<EFBFBD><CBB7>ֻ<EFBFBD>û<EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>¼û<C2BC>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ۲<C4B9><DBB2><EFBFBD><EFBFBD><EFBFBD> */
// if ((int) (tickget() - tick) >= svr->cycle)
// {
// svr->prcout += fobs[0] - i - 1;
// }
2022-06-22 09:23:36 +08:00
/* send null solution if no solution (1hz) */
if (svr->rtk.sol.stat == SOLQ_NONE && (int) (tick - tick1hz) >= 1000)
{
// writesol_mini(svr, 0);
tick1hz = tick;
}
/* send nmea request to base/nrtk input stream */
if (svr->nmeacycle > 0 && (int) (tick - ticknmea) >= svr->nmeacycle)
{
// TODO: <20><><EFBFBD><EFBFBD>send_nmea <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>ֲ
// send_nmea(svr, &tickreset);
ticknmea = tick;
}
cputime = (int) (tickget() - tick);
if (cputime > 0)
svr->cputime = cputime;
/* sleep until next cycle */
2022-06-16 18:57:17 +08:00
}
}
sleepms(1);
2022-06-16 18:57:17 +08:00
}
static void user_init_task(rt_thread_t thread, const char *name, void (*entry)(void *parameter), void *stack_start,
rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick, rt_uint32_t start)
{
rt_err_t result = RT_EOK;
result = rt_thread_init(thread, name, entry, RT_NULL, stack_start, stack_size, priority, tick);
if (start)
{
if (result == RT_EOK)
{
rt_thread_startup(thread);
}
else
{
LOG_E("task init failed :%s", name);
}
}
}
/*===========================================================================================================*/
2022-06-22 09:23:36 +08:00
2022-06-16 18:57:17 +08:00
void task_init(void)
{
2022-06-22 09:23:36 +08:00
rt_event_init(&uart_event, "uart_event", RT_IPC_FLAG_PRIO);
rt_mutex_init(&userf_svrlock, "svrlock", RT_IPC_FLAG_PRIO);
2022-06-22 09:23:36 +08:00
rt_completion_init(&rtcm_user_data_process_completion);
rt_completion_init(&rtcm_ref_data_process_completion);
rt_thread_t trd = rt_thread_create("rtk_proces", thread_rtk_proces, RT_NULL, 8000, thread_rtk_proces_priority,
DEFAULT_USER_THREA_TICK);
2022-06-22 09:23:36 +08:00
rt_thread_startup(trd);
user_init_task(&get_user_rtcm_data, "thread_get_user_rtcm_data", thread_get_user_rtcm_data,
thread_user_rtcm_data_stack,
get_rtcm_user_data_stack_size, THREAD_get_user_rtcm_data_priority, DEFAULT_USER_THREA_TICK, RT_TRUE);
user_init_task(&get_ref_rtcm_data, "thread_get_ref_rtcm_data", thread_get_ref_rtcm_data, thread_ref_rtcm_data_stack,
get_rtcm_ref_data_stack_size, THREAD_get_ref_rtcm_data_priority, DEFAULT_USER_THREA_TICK, RT_TRUE);
2022-06-22 09:23:36 +08:00
// user_init_task(&rtk_proces, "rtk_proces", thread_rtk_proces, thread_rtk_proces_stack,
// rtk_proces_stack_size, thread_rtk_proces_priority, DEFAULT_USER_THREA_TICK, RT_TRUE);
2022-06-16 18:57:17 +08:00
}