NR UE: provide velocity vector down to nr-ue.c, preparing for Doppler calculation
This commit is contained in:
+32
-11
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user