NR UE: provide velocity vector down to nr-ue.c, preparing for Doppler calculation

This commit is contained in:
Thomas Schlichter
2025-12-19 16:38:59 +01:00
parent 479be40b30
commit b59bcaf494
6 changed files with 81 additions and 24 deletions
+32 -11
View File
@@ -732,15 +732,32 @@ static inline void apply_ntn_timing_advance(PHY_VARS_NR_UE *UE, const NR_DL_FRAM
+ ntn_config_params->epoch_hfn * 10240; + ntn_config_params->epoch_hfn * 10240;
const int ms_since_epoch = abs_subframe_tx - abs_subframe_epoch; const int ms_since_epoch = abs_subframe_tx - abs_subframe_epoch;
const double omega = ntn_config_params->omega;
const double cos_wt = cos(omega * ms_since_epoch);
const double sin_wt = sin(omega * ms_since_epoch);
const position_t pos_sat_0 = ntn_config_params->pos_sat_0; const position_t pos_sat_0 = ntn_config_params->pos_sat_0;
const position_t pos_sat_90 = ntn_config_params->pos_sat_90; const position_t vel_sat_0 = ntn_config_params->vel_sat_0;
const position_t pos_sat = {pos_sat_0.X * cos_wt + pos_sat_90.X * sin_wt,
pos_sat_0.Y * cos_wt + pos_sat_90.Y * sin_wt, position_t pos_sat;
pos_sat_0.Z * cos_wt + pos_sat_90.Z * sin_wt}; position_t vel_sat;
const double omega = ntn_config_params->omega;
if (omega) {
const double cos_wt = cos(omega * ms_since_epoch);
const double sin_wt = sin(omega * ms_since_epoch);
const position_t pos_sat_90 = ntn_config_params->pos_sat_90;
pos_sat = (position_t){pos_sat_0.X * cos_wt + pos_sat_90.X * sin_wt,
pos_sat_0.Y * cos_wt + pos_sat_90.Y * sin_wt,
pos_sat_0.Z * cos_wt + pos_sat_90.Z * sin_wt};
const position_t vel_sat_90 = ntn_config_params->vel_sat_90;
vel_sat = (position_t){vel_sat_0.X * cos_wt + vel_sat_90.X * sin_wt,
vel_sat_0.Y * cos_wt + vel_sat_90.Y * sin_wt,
vel_sat_0.Z * cos_wt + vel_sat_90.Z * sin_wt};
} else {
pos_sat = (position_t){pos_sat_0.X + vel_sat_0.X * ms_since_epoch / 1000,
pos_sat_0.Y + vel_sat_0.Y * ms_since_epoch / 1000,
pos_sat_0.Z + vel_sat_0.Z * ms_since_epoch / 1000};
vel_sat = vel_sat_0;
}
position_t pos_ue = {0}; position_t pos_ue = {0};
get_position_coordinates(UE->Mod_id, &pos_ue); get_position_coordinates(UE->Mod_id, &pos_ue);
@@ -751,6 +768,9 @@ static inline void apply_ntn_timing_advance(PHY_VARS_NR_UE *UE, const NR_DL_FRAM
// calculate distance between SAT and UE // calculate distance between SAT and UE
const double distance = sqrt(dir_sat_ue.X * dir_sat_ue.X + dir_sat_ue.Y * dir_sat_ue.Y + dir_sat_ue.Z * dir_sat_ue.Z); const double distance = sqrt(dir_sat_ue.X * dir_sat_ue.X + dir_sat_ue.Y * dir_sat_ue.Y + dir_sat_ue.Z * dir_sat_ue.Z);
// calculate projected velocity from SAT towards UE
const double vel_sat_ue = (vel_sat.X * dir_sat_ue.X + vel_sat.Y * dir_sat_ue.Y + vel_sat.Z * dir_sat_ue.Z) / distance;
// calculate round-trip-time (factor 2) between SAT and UE in ms (factor 1000) // calculate round-trip-time (factor 2) between SAT and UE in ms (factor 1000)
const double N_UE_TA_adj = 2000 * distance / SPEED_OF_LIGHT; const double N_UE_TA_adj = 2000 * distance / SPEED_OF_LIGHT;
@@ -764,14 +784,15 @@ static inline void apply_ntn_timing_advance(PHY_VARS_NR_UE *UE, const NR_DL_FRAM
* fp->samples_per_subframe; * fp->samples_per_subframe;
LOG_D(PHY, LOG_D(PHY,
"N_UE_TA_adj = %f ms, N_common_ta_adj = %f ms, N_common_ta_drift = %f µs/s, N_common_ta_drift_variant = %f µs/s², ms_since_epoch = %d ms, " "N_UE_TA_adj = %f ms, N_common_ta_adj = %f ms, N_common_ta_drift = %f µs/s, N_common_ta_drift_variant = %f µs/s², "
"computed timing_advance_ntn = %d samples\n", "ms_since_epoch = %d ms, computed timing_advance_ntn = %d samples, satellite velocity towards UE = %f m/s\n",
N_UE_TA_adj, N_UE_TA_adj,
N_common_ta_adj, N_common_ta_adj,
N_common_ta_drift, N_common_ta_drift,
N_common_ta_drift_variant, N_common_ta_drift_variant,
ms_since_epoch, ms_since_epoch,
UE->timing_advance_ntn); UE->timing_advance_ntn,
vel_sat_ue);
} }
static inline void apply_ntn_config(PHY_VARS_NR_UE *UE, static inline void apply_ntn_config(PHY_VARS_NR_UE *UE,
@@ -569,10 +569,14 @@ typedef struct {
// orbital angular velocity in rad/ms // orbital angular velocity in rad/ms
double omega; double omega;
// satellite position at epoch time // satellite position vector at epoch time
position_t pos_sat_0; position_t pos_sat_0;
// satellite position at 90° orbit // satellite position vector at 90° orbit
position_t pos_sat_90; position_t pos_sat_90;
// satellite velocity vector at epoch time
position_t vel_sat_0;
// satellite velocity vector at 90° orbit
position_t vel_sat_90;
// N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms) // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
double N_common_ta_adj; double N_common_ta_adj;
+2
View File
@@ -102,6 +102,8 @@ static void configure_ntn_params(PHY_VARS_NR_UE *ue, fapi_nr_dl_ntn_config_comma
ue->ntn_config_message->ntn_config_params.omega = ntn_params_message->omega; ue->ntn_config_message->ntn_config_params.omega = ntn_params_message->omega;
ue->ntn_config_message->ntn_config_params.pos_sat_0 = ntn_params_message->pos_sat_0; ue->ntn_config_message->ntn_config_params.pos_sat_0 = ntn_params_message->pos_sat_0;
ue->ntn_config_message->ntn_config_params.pos_sat_90 = ntn_params_message->pos_sat_90; ue->ntn_config_message->ntn_config_params.pos_sat_90 = ntn_params_message->pos_sat_90;
ue->ntn_config_message->ntn_config_params.vel_sat_0 = ntn_params_message->vel_sat_0;
ue->ntn_config_message->ntn_config_params.vel_sat_90 = ntn_params_message->vel_sat_90;
ue->ntn_config_message->ntn_config_params.N_common_ta_adj = ntn_params_message->N_common_ta_adj; ue->ntn_config_message->ntn_config_params.N_common_ta_adj = ntn_params_message->N_common_ta_adj;
ue->ntn_config_message->ntn_config_params.N_common_ta_drift = ntn_params_message->N_common_ta_drift; ue->ntn_config_message->ntn_config_params.N_common_ta_drift = ntn_params_message->N_common_ta_drift;
+33 -9
View File
@@ -279,29 +279,49 @@ static void prepare_ue_sat_ta(const NR_PositionVelocity_r17_t *sat_pos, ntn_timi
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 vel_sat_2 = vel_sat.X * vel_sat.X + vel_sat.Y * vel_sat.Y + vel_sat.Z * vel_sat.Z;
const double vel_mag = sqrt(vel_sat_2); const double vel_mag = sqrt(vel_sat_2);
// calculate angular velocity in rad/ms double omega; // angular velocity in rad/ms
const double omega = vel_mag / (radius * 1000); position_t pos_sat_90; // sat position vector in 90° orbit
position_t vel_sat_90; // sat velocity vector in 90° orbit
// calculate sat position in 90° orbit // assuming circular orbit when satellite moves faster than 1000 m/s
position_t pos_sat_90 = pos_sat; // 1000 m/s are chosen because according to Wikipedia, this seems to be a reasonable minimal
if (vel_mag) { // orbital velocity: https://en.wikipedia.org/wiki/Orbital_speed#Tangential_velocities_at_altitude
const double scaling = radius / vel_mag; if (vel_mag > 1000) {
omega = vel_mag / (radius * 1000);
double scaling = radius / vel_mag;
pos_sat_90 = (position_t){vel_sat.X * scaling, vel_sat.Y * scaling, vel_sat.Z * scaling}; pos_sat_90 = (position_t){vel_sat.X * scaling, vel_sat.Y * scaling, vel_sat.Z * scaling};
scaling = -vel_mag / radius;
vel_sat_90 = (position_t){pos_sat.X * scaling, pos_sat.Y * scaling, pos_sat.Z * scaling};
} else {
omega = 0;
pos_sat_90 = pos_sat;
vel_sat_90 = vel_sat;
} }
LOG_I(NR_MAC, LOG_I(NR_MAC,
"Satellite angular velocity = %e rad/ms, sat_pos = {%f, %f, %f}, sat_pos_90 = {%f, %f, %f}\n", "Satellite orbital radius %f m, pos_sat_0 = {%f, %f, %f}, pos_sat_90 = {%f, %f, %f}\n"
omega, "Satellite velocity %f m/s, angular velocity = %e rad/ms, vel_sat_0 = {%f, %f, %f}, vel_sat_90 = {%f, %f, %f}\n",
radius,
pos_sat.X, pos_sat.X,
pos_sat.Y, pos_sat.Y,
pos_sat.Z, pos_sat.Z,
pos_sat_90.X, pos_sat_90.X,
pos_sat_90.Y, pos_sat_90.Y,
pos_sat_90.Z); pos_sat_90.Z,
vel_mag,
omega,
vel_sat.X,
vel_sat.Y,
vel_sat.Z,
vel_sat_90.X,
vel_sat_90.Y,
vel_sat_90.Z);
ntn_ta->omega = omega; ntn_ta->omega = omega;
ntn_ta->pos_sat_0 = pos_sat; ntn_ta->pos_sat_0 = pos_sat;
ntn_ta->pos_sat_90 = pos_sat_90; ntn_ta->pos_sat_90 = pos_sat_90;
ntn_ta->vel_sat_0 = vel_sat;
ntn_ta->vel_sat_90 = vel_sat_90;
} }
// populate ntn_ta structure from mac // populate ntn_ta structure from mac
@@ -332,11 +352,15 @@ static void configure_ntn_ta(ntn_timing_advance_componets_t *ntn_ta, const NR_NT
ntn_ta->omega = 0; ntn_ta->omega = 0;
ntn_ta->pos_sat_0 = (position_t){0, 0, 0}; ntn_ta->pos_sat_0 = (position_t){0, 0, 0};
ntn_ta->pos_sat_90 = (position_t){0, 0, 0}; ntn_ta->pos_sat_90 = (position_t){0, 0, 0};
ntn_ta->vel_sat_0 = (position_t){0, 0, 0};
ntn_ta->vel_sat_90 = (position_t){0, 0, 0};
} }
} else { // Need R - Release if not present } else { // Need R - Release if not present
ntn_ta->omega = 0; ntn_ta->omega = 0;
ntn_ta->pos_sat_0 = (position_t){0, 0, 0}; ntn_ta->pos_sat_0 = (position_t){0, 0, 0};
ntn_ta->pos_sat_90 = (position_t){0, 0, 0}; ntn_ta->pos_sat_90 = (position_t){0, 0, 0};
ntn_ta->vel_sat_0 = (position_t){0, 0, 0};
ntn_ta->vel_sat_90 = (position_t){0, 0, 0};
} }
// handle cellSpecificKoffset_r17 // handle cellSpecificKoffset_r17
+6 -2
View File
@@ -552,10 +552,14 @@ typedef struct ntn_timing_advance_components {
// orbital angular velocity in rad/ms // orbital angular velocity in rad/ms
double omega; double omega;
// satellite position at epoch time // satellite position vector at epoch time
position_t pos_sat_0; position_t pos_sat_0;
// satellite position at 90° orbit // satellite position vector at 90° orbit
position_t pos_sat_90; position_t pos_sat_90;
// satellite velocity vector at epoch time
position_t vel_sat_0;
// satellite velocity vector at 90° orbit
position_t vel_sat_90;
// N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms) // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
double N_common_ta_adj; double N_common_ta_adj;
@@ -2855,6 +2855,8 @@ static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config,
ntn_config_command_pdu->omega = mac->ntn_ta.omega; ntn_config_command_pdu->omega = mac->ntn_ta.omega;
ntn_config_command_pdu->pos_sat_0 = mac->ntn_ta.pos_sat_0; ntn_config_command_pdu->pos_sat_0 = mac->ntn_ta.pos_sat_0;
ntn_config_command_pdu->pos_sat_90 = mac->ntn_ta.pos_sat_90; ntn_config_command_pdu->pos_sat_90 = mac->ntn_ta.pos_sat_90;
ntn_config_command_pdu->vel_sat_0 = mac->ntn_ta.vel_sat_0;
ntn_config_command_pdu->vel_sat_90 = mac->ntn_ta.vel_sat_90;
ntn_config_command_pdu->N_common_ta_adj = mac->ntn_ta.N_common_ta_adj; ntn_config_command_pdu->N_common_ta_adj = mac->ntn_ta.N_common_ta_adj;
ntn_config_command_pdu->N_common_ta_drift = mac->ntn_ta.N_common_ta_drift; ntn_config_command_pdu->N_common_ta_drift = mac->ntn_ta.N_common_ta_drift;