Merge remote-tracking branch 'origin/sib19-ue-utilization' into integration_2024_w50 (!3019)

SIB19 utilization on UE

Following SIB19 initialization and scheduling on gNB (!2899 - merged)
and Receive SIB19 on nrUE (!2920 - merged), this merge request aims to
introduce the actual use of the SIB19 provided parameters by gNB in UE.
Changes needed for utilization include: initialization of position
coordinates parameters for UE (which are needed to calculate propagation
delay between UE and SAT), propagation delay calculations and timing
advance adjusts. Moreover, this change removes the now unused arguments
for ntn_koffset, ntn_ta_common and ntn_ta_commondrift
This commit is contained in:
Robert Schmidt
2024-12-16 15:26:48 +01:00
27 changed files with 405 additions and 136 deletions
+63 -15
View File
@@ -41,6 +41,7 @@
#include "PHY/MODULATION/nr_modulation.h"
#include "instrumentation.h"
#include "common/utils/threadPool/notified_fifo.h"
#include "position_interface.h"
/*
* NR SLOT PROCESSING SEQUENCE
@@ -155,7 +156,9 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id)
ue->if_inst = nr_ue_if_module_init(UE_id);
ue->dci_thres = 0;
ue->target_Nid_cell = -1;
ue->timing_advance = ue->frame_parms.samples_per_subframe * get_nrUE_params()->ntn_ta_common;
ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message));
ue->ntn_config_message->update = false;
// initialize all signal buffers
init_nr_ue_signal(ue, nb_connected_gNB);
@@ -481,8 +484,23 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
}
}
int tmp = openair0_write_reorder(&UE->rfdevice, proc->timestamp_tx, txp, rxtxD->writeBlockSize, fp->nb_antennas_tx, flags);
AssertFatal(tmp == rxtxD->writeBlockSize, "");
openair0_timestamp writeTimestamp = proc->timestamp_tx;
int writeBlockSize = rxtxD->writeBlockSize;
if ( writeBlockSize > fp->get_samples_per_slot(proc->nr_slot_tx, fp)) {
// if writeBlockSize gets longer that slot size, fill with dummy
const int dummyBlockSize = writeBlockSize - fp->get_samples_per_slot(proc->nr_slot_tx, fp);
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, dummyBlockSize, fp->nb_antennas_tx, flags);
AssertFatal(tmp == dummyBlockSize, "");
writeTimestamp += dummyBlockSize;
writeBlockSize -= dummyBlockSize;
}
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, writeBlockSize, fp->nb_antennas_tx, flags);
AssertFatal(tmp == writeBlockSize, "");
for (int i = 0; i < fp->nb_antennas_tx; i++)
memset(txp[i], 0, writeBlockSize);
}
void processSlotTX(void *arg)
@@ -548,8 +566,8 @@ void processSlotTX(void *arg)
int slots_per_frame = (UE->sl_mode == 2) ? UE->SL_UE_PHY_PARAMS.sl_frame_params.slots_per_frame
: UE->frame_parms.slots_per_frame;
int next_slot = (proc->nr_slot_tx + 1) % slots_per_frame;
dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot]);
int next_slot_and_frame = proc->nr_slot_tx + 1 + proc->nr_slot_tx_offset + proc->frame_tx * slots_per_frame;
dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]);
RU_write(rxtxD, sl_tx_action);
free(rxtxD);
TracyCZoneEnd(ctx);
@@ -824,8 +842,7 @@ void *UE_thread(void *arg)
int absolute_slot = 0, decoded_frame_rx = MAX_FRAME_NUMBER - 1, trashed_frames = 0;
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
int num_ind_fifo = nb_slot_frame;
for(int i = 0; i < num_ind_fifo; i++) {
for(int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) {
dynamic_barrier_init(&UE->process_slot_tx_barriers[i]);
}
int shiftForNextFrame = 0;
@@ -836,13 +853,21 @@ void *UE_thread(void *arg)
if (get_softmodem_params()->sync_ref && UE->sl_mode == 2) {
UE->is_synchronized = 1;
} else {
//warm up the RF board
//warm up the RF board
int64_t tmp;
for (int i = 0; i < 50; i++)
readFrame(UE, &tmp, true);
}
double ntn_ta_common = 0;
int ntn_koffset = 0;
int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX;
int nr_slot_tx_offset = 0;
bool update_ntn_system_information = false;
while (!oai_exit) {
nr_slot_tx_offset = 0;
if (syncRunning) {
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&nf);
@@ -913,7 +938,7 @@ void *UE_thread(void *arg)
openair0_write_reorder_clear_context(&UE->rfdevice);
if (get_nrUE_params()->time_sync_I)
// ntn_ta_commondrift is in µs/s, max_pos_acc * time_sync_I is in samples/frame
UE->max_pos_acc = get_nrUE_params()->ntn_ta_commondrift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I;
UE->max_pos_acc = mac->ntn_ta.ntn_ta_commondrift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I;
else
UE->max_pos_acc = 0;
shiftForNextFrame = -(UE->init_sync_frame + trashed_frames + 2) * UE->max_pos_acc * get_nrUE_params()->time_sync_I; // compensate for the time drift that happened during initial sync
@@ -940,7 +965,7 @@ void *UE_thread(void *arg)
}
// We have resynchronized, maybe after RF loss so we need to purge any existing context
memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch));
for (int i = 0; i < num_ind_fifo; i++) {
for (int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) {
dynamic_barrier_reset(&UE->process_slot_tx_barriers[i]);
}
continue;
@@ -954,14 +979,30 @@ void *UE_thread(void *arg)
absolute_slot++;
TracyCFrameMark;
if (update_ntn_system_information) {
update_ntn_system_information = false;
int ta_offset = UE->frame_parms.samples_per_subframe * (UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms - ntn_ta_common);
UE->timing_advance += ta_offset;
ntn_ta_common = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms;
ntn_koffset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset;
timing_advance = ntn_koffset * (UE->frame_parms.samples_per_subframe >> mac->current_UL_BWP->scs);
}
if (UE->ntn_config_message->update) {
UE->ntn_config_message->update = false;
update_ntn_system_information = true;
nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset;
}
int slot_nr = absolute_slot % nb_slot_frame;
nr_rxtx_thread_data_t curMsg = {0};
curMsg.UE=UE;
// update thread index for received subframe
curMsg.proc.nr_slot_rx = slot_nr;
curMsg.proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg.proc.nr_slot_tx = (absolute_slot + duration_rx_to_tx) % nb_slot_frame;
curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg.proc.frame_tx = ((absolute_slot + duration_rx_to_tx) / nb_slot_frame) % MAX_FRAME_NUMBER;
if (UE->received_config_request) {
if (UE->sl_mode) {
curMsg.proc.rx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_rx, TDD);
@@ -1014,11 +1055,11 @@ void *UE_thread(void *arg)
}
// use previous timing_advance value to compute writeTimestamp
const openair0_timestamp writeTimestamp = rx_timestamp + fp->get_samples_slot_timestamp(slot_nr, fp, DURATION_RX_TO_TX)
const openair0_timestamp writeTimestamp = rx_timestamp + fp->get_samples_slot_timestamp(slot_nr, fp, duration_rx_to_tx)
- firstSymSamp - UE->N_TA_offset - timing_advance;
// but use current UE->timing_advance value to compute writeBlockSize
int writeBlockSize = fp->get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, fp) - iq_shift_to_apply;
int writeBlockSize = fp->get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply;
if (UE->timing_advance != timing_advance) {
writeBlockSize -= UE->timing_advance - timing_advance;
timing_advance = UE->timing_advance;
@@ -1044,15 +1085,22 @@ void *UE_thread(void *arg)
curMsgTx->proc.timestamp_tx = writeTimestamp;
curMsgTx->UE = UE;
curMsgTx->stream_status = stream_status;
curMsgTx->proc.nr_slot_tx_offset = nr_slot_tx_offset;
int sync_to_previous_thread = stream_status == STREAM_STATUS_SYNCED ? 1 : 0;
int slot = curMsgTx->proc.nr_slot_tx;
dynamic_barrier_update(&UE->process_slot_tx_barriers[slot],
int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame;
dynamic_barrier_update(&UE->process_slot_tx_barriers[slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS],
tx_wait_for_dlsch[slot] + sync_to_previous_thread,
start_process_slot_tx,
curMsgTx);
stream_status = STREAM_STATUS_SYNCED;
tx_wait_for_dlsch[slot] = 0;
// apply new duration next run to avoid thread dead lock
if (update_ntn_system_information) {
duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset;
}
}
return NULL;
-6
View File
@@ -129,9 +129,6 @@ int otg_enabled;
double cpuf;
uint32_t N_RB_DL = 106;
// NTN cellSpecificKoffset-r17, but in slots for DL SCS
unsigned int NTN_UE_Koffset = 0;
int create_tasks_nrue(uint32_t ue_nb) {
LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
itti_wait_ready(1);
@@ -518,9 +515,6 @@ int main(int argc, char **argv)
}
}
// NTN cellSpecificKoffset-r17, but in slots for DL SCS
NTN_UE_Koffset = nrUE_params.ntn_koffset << PHY_vars_UE_g[0][0]->frame_parms.numerology_index;
init_openair0();
lock_memory_to_ram();
-9
View File
@@ -12,9 +12,6 @@
#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
#define CONFIG_HLP_TIME_SYNC_P "coefficient for Proportional part of time sync PI controller\n"
#define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n"
#define CONFIG_HLP_NTN_KOFFSET "NTN cellSpecificKoffset-r17 (number of slots for a given subcarrier spacing of 15 kHz)\n"
#define CONFIG_HLP_NTN_TA_COMMON "NTN ta-Common, but given in ms\n"
#define CONFIG_HLP_NTN_TA_COMMONDRIFT "NTN ta-CommonDrift, but given in µs/s\n"
#define CONFIG_HLP_AUTONOMOUS_TA "Autonomously update TA based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite)\n"
#define CONFIG_HLP_AGC "Rx Gain control used for UE\n"
@@ -67,9 +64,6 @@
{"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \
{"time-sync-P", CONFIG_HLP_TIME_SYNC_P, 0, .dblptr=&(nrUE_params.time_sync_P), .defdblval=0.5, TYPE_DOUBLE, 0}, \
{"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \
{"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"ntn-ta-commondrift", CONFIG_HLP_NTN_TA_COMMONDRIFT, 0, .dblptr=&(nrUE_params.ntn_ta_commondrift), .defdblval=0.0, TYPE_DOUBLE, 0}, \
{"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \
{"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \
}
@@ -94,9 +88,6 @@ typedef struct {
int ldpc_offload_flag;
double time_sync_P;
double time_sync_I;
unsigned int ntn_koffset;
double ntn_ta_common;
double ntn_ta_commondrift;
int autonomous_ta;
int agc;
char *usrp_args;
+39
View File
@@ -0,0 +1,39 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "position_interface.h"
extern uint16_t NB_UE_INST;
static void read_position_coordinates(char *sectionName, position_t *position)
{
paramdef_t position_params[] = POSITION_CONFIG_PARAMS_DEF;
int ret = config_get(config_get_if(), position_params, sizeofArray(position_params), sectionName);
AssertFatal(ret >= 0, "configuration couldn't be performed for position name: %s", sectionName);
}
void get_position_coordinates(int Mod_id, position_t *position)
{
AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id, NB_UE_INST);
char positionName[64];
snprintf(positionName, sizeof(positionName), "position%d", Mod_id);
read_position_coordinates(positionName, position);
}
+58
View File
@@ -0,0 +1,58 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __POSITION_INTERFACE__H__
#define __POSITION_INTERFACE__H__
#include <executables/nr-softmodem-common.h>
#include <executables/softmodem-common.h>
#include "PHY/defs_nr_UE.h"
#include "executables/nr-uesoftmodem.h"
/* position configuration parameters name */
#define CONFIG_STRING_POSITION_X "x"
#define CONFIG_STRING_POSITION_Y "y"
#define CONFIG_STRING_POSITION_Z "z"
#define HELP_STRING_POSITION "Postion coordinates (x, y, z) config params"
// Position parameters config
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* position configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
// clang-format off
#define POSITION_CONFIG_PARAMS_DEF { \
{CONFIG_STRING_POSITION_X, HELP_STRING_POSITION, 0, .dblptr=&(position->positionX), .defuintval=0, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_POSITION_Y, HELP_STRING_POSITION, 0, .dblptr=&(position->positionY), .defuintval=0, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_POSITION_Z, HELP_STRING_POSITION, 0, .dblptr=&(position->positionZ), .defuintval=0, TYPE_DOUBLE, 0} \
}
// clang-format on
typedef struct position {
double positionX;
double positionY;
double positionZ;
} position_t;
void get_position_coordinates(int Mod_id, position_t *position);
#endif