From eb6c195c9b12ccde3475a68d065877026336f08b Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Sat, 9 Aug 2025 07:37:35 +0200 Subject: [PATCH] NR UE NTN: consider acceleration on orbital path to calculate N_UE_TA_drift_variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The acceleration magnitude on the orbital path can be calculated as: t = 2 * pi * r / v omega = 2 * pi / t = v / r acceleration = omega² * r = v² / r Where t is the orbital period, r is the orbital radius, v is the orbital velocity, omega is the angular velocity. The acceleration direction is from the SAT position towards the earth center. To calculate the acceleration towards the UE, this is projected on the direction from the SAT to the UE. --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 17 +++++++++++++++-- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 7 +++++++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index f79a5628b7..73bb02a575 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -289,8 +289,17 @@ static void calculate_ue_sat_ta(const position_t *position_params, // calculate SAT velocity towards UE double velocity = (vel_sat.X * dir_sat_ue.X + vel_sat.Y * dir_sat_ue.Y + vel_sat.Z * dir_sat_ue.Z) / distance; + // calculate SAT acceleration towards UE + const double radius_2 = pos_sat.X * pos_sat.X + pos_sat.Y * pos_sat.Y + pos_sat.Z * pos_sat.Z; + const double vel_sat_2 = vel_sat.X * vel_sat.X + vel_sat.Y * vel_sat.Y + vel_sat.Z * vel_sat.Z; + const double acceleration = + -(pos_sat.X * dir_sat_ue.X + pos_sat.Y * dir_sat_ue.Y + pos_sat.Z * dir_sat_ue.Z) * vel_sat_2 / (radius_2 * distance); + + LOG_D(NR_MAC, "Satellite velocity towards UE: %f m/s, acceleration towards UE: %f m/s²\n", velocity, acceleration); + ntn_ta->N_UE_TA_adj = (2 * distance / SPEED_OF_LIGHT) * 1e3; // in ms ntn_ta->N_UE_TA_drift = (2 * -velocity / SPEED_OF_LIGHT) * 1e6; // in µs/s + ntn_ta->N_UE_TA_drift_variant = (2 * acceleration / SPEED_OF_LIGHT) * 1e6; // in µs/s² } // populate ntn_ta structure from mac @@ -321,10 +330,12 @@ static void configure_ntn_ta(module_id_t module_id, LOG_W(NR_MAC, "NR UE currently supports only ephemerisInfo_r17 of type positionVelocity_r17\n"); ntn_ta->N_UE_TA_adj = 0; ntn_ta->N_UE_TA_drift = 0; + ntn_ta->N_UE_TA_drift_variant = 0; } } else { // Need R - Release if not present ntn_ta->N_UE_TA_adj = 0; ntn_ta->N_UE_TA_drift = 0; + ntn_ta->N_UE_TA_drift_variant = 0; } // handle cellSpecificKoffset_r17 @@ -356,7 +367,8 @@ static void configure_ntn_ta(module_id_t module_id, ntn_ta->ntn_params_changed = true; LOG_D(NR_MAC, - "SIB19 Rxd. Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, N_Common_Ta: %fms, drift: %fµs/s, variant %fµs/s², N_UE_TA: %fms, drift: %fµs/s\n", + "SIB19 Rxd. Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, N_Common_Ta: %fms, drift: %fµs/s, variant %fµs/s², " + "N_UE_TA: %fms, drift: %fµs/s, variant %fµs/s²\n", ntn_ta->epoch_sfn, ntn_ta->epoch_subframe, ntn_ta->cell_specific_k_offset, @@ -364,7 +376,8 @@ static void configure_ntn_ta(module_id_t module_id, ntn_ta->N_common_ta_drift, ntn_ta->N_common_ta_drift_variant, ntn_ta->N_UE_TA_adj, - ntn_ta->N_UE_TA_drift); + ntn_ta->N_UE_TA_drift, + ntn_ta->N_UE_TA_drift_variant); } static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 9abe9751cb..2d88708bfe 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -541,6 +541,8 @@ typedef struct ntn_timing_advance_components { double N_UE_TA_adj; // drift rate of N_UE_TA in µs/s double N_UE_TA_drift; + // change rate of N_UE_TA drift in µs/s² + double N_UE_TA_drift_variant; // cell scheduling offset expressed in terms of 15kHz SCS long cell_specific_k_offset; @@ -674,5 +676,10 @@ static inline double get_total_TA_drift(const ntn_timing_advance_componets_t *nt return ntn_ta->N_common_ta_drift + ntn_ta->N_UE_TA_drift; } +static inline double get_total_TA_drift_variant(const ntn_timing_advance_componets_t *ntn_ta) +{ + return ntn_ta->N_common_ta_drift_variant + ntn_ta->N_UE_TA_drift_variant; +} + /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 76836834f0..b95597a0ba 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2854,7 +2854,7 @@ static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, ntn_config_command_pdu->cell_specific_k_offset = mac->ntn_ta.cell_specific_k_offset; ntn_config_command_pdu->ntn_total_time_advance_ms = get_total_TA_ms(&mac->ntn_ta); ntn_config_command_pdu->ntn_total_time_advance_drift = get_total_TA_drift(&mac->ntn_ta); - ntn_config_command_pdu->ntn_total_time_advance_drift_variant = mac->ntn_ta.N_common_ta_drift_variant; + ntn_config_command_pdu->ntn_total_time_advance_drift_variant = get_total_TA_drift_variant(&mac->ntn_ta); dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_NTN_CONFIG_PARAMS; dl_config->number_pdus += 1;