Skip to content

Commit

Permalink
ptp: use pi controller to fine tune the coefficient (OpenVisualCloud#124
Browse files Browse the repository at this point in the history
)

Signed-off-by: Ric Li <ming3.li@intel.com>
  • Loading branch information
ricmli authored Dec 28, 2022
1 parent 76d5eb0 commit 8bdf8a0
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
15 changes: 15 additions & 0 deletions app/src/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ enum st_args_cmd {
ST_ARG_TASKLET_SLEEP_US,
ST_ARG_APP_THREAD,
ST_ARG_RXTX_SIMD_512,
ST_ARG_PTP_PI,
ST_ARG_PTP_KP,
ST_ARG_PTP_KI,
ST_ARG_MAX,
};

Expand Down Expand Up @@ -165,6 +168,9 @@ static struct option st_app_args_options[] = {
{"tasklet_sleep_us", required_argument, 0, ST_ARG_TASKLET_SLEEP_US},
{"app_thread", no_argument, 0, ST_ARG_APP_THREAD},
{"rxtx_simd_512", no_argument, 0, ST_ARG_RXTX_SIMD_512},
{"pi", no_argument, 0, ST_ARG_PTP_PI},
{"kp", required_argument, 0, ST_ARG_PTP_KP},
{"ki", required_argument, 0, ST_ARG_PTP_KI},

{0, 0, 0, 0}};

Expand Down Expand Up @@ -508,6 +514,15 @@ int st_app_parse_args(struct st_app_context* ctx, struct mtl_init_params* p, int
case ST_ARG_RXTX_SIMD_512:
p->flags |= MTL_FLAG_RXTX_SIMD_512;
break;
case ST_ARG_PTP_PI:
p->flags |= MTL_FLAG_PTP_PI;
break;
case ST_ARG_PTP_KP:
p->kp = strtod(optarg, NULL);
break;
case ST_ARG_PTP_KI:
p->ki = strtod(optarg, NULL);
break;
case '?':
break;
default:
Expand Down
13 changes: 13 additions & 0 deletions include/mtl_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ enum st21_tx_pacing_way {
* Enable shared queue for tx and rx, only support in MTL_TRANSPORT_UDP now.
*/
#define MTL_FLAG_SHARED_QUEUE (MTL_BIT64(8))
/**
* Flag bit in flags of struct mtl_init_params.
* Use PI controller for built-in PTP implementation, only for PF now.
*/
#define MTL_FLAG_PTP_PI (MTL_BIT64(9))

/**
* Flag bit in flags of struct mtl_init_params, debug usage only.
Expand Down Expand Up @@ -412,6 +417,14 @@ struct mtl_init_params {
* The st21 tx pacing way, leave to zero(auto) if you don't known the detail.
*/
enum st21_tx_pacing_way pacing;
/**
* The ptp pi controller proportional gain.
*/
double kp;
/**
* The ptp pi controller integral gain.
*/
double ki;
};

/**
Expand Down
7 changes: 7 additions & 0 deletions lib/src/mt_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ struct mt_ptp_impl {
double coefficient_result_max;
int32_t coefficient_result_cnt;

/* pi controller */
bool use_pi; /* use pi controller */
double kp; /* proportional gain */
double ki; /* integral gain */
double integral; /* integral value */
int64_t prev_error; /* previous error (correct_delta) */

/* status */
int64_t stat_delta_min;
int64_t stat_delta_max;
Expand Down
31 changes: 28 additions & 3 deletions lib/src/mt_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

#define MT_PTP_EBU_SYNC_MS (10)

#define MT_PTP_DEFAULT_KP 5e-10 /* to be tuned */
#define MT_PTP_DEFAULT_KI 1e-10 /* to be tuned */

static char* ptp_mode_strs[MT_PTP_MAX_MODE] = {
"l2",
"l4",
Expand Down Expand Up @@ -115,6 +118,15 @@ static void ptp_coeffcient_result_reset(struct mt_ptp_impl* ptp) {
ptp->coefficient_result_cnt = 0;
}

static void ptp_update_coefficient(struct mt_ptp_impl* ptp, int64_t error) {
ptp->integral += (error + ptp->prev_error) / 2;
ptp->prev_error = error;
double offset = ptp->kp * error + ptp->ki * ptp->integral;
if (ptp->t2_mode == MT_PTP_L4) offset /= 4; /* where sync interval is 0.25s for l4 */
ptp->coefficient += RTE_MIN(RTE_MAX(offset, -1e-7), 1e-7);
dbg("%s(%d), error %" PRId64 ", offset %.15lf\n", __func__, ptp->port, error, offset);
}

static void ptp_calculate_coefficient(struct mt_ptp_impl* ptp, int64_t delta) {
if (delta > 1000 * 1000) return;
uint64_t ts_s = ptp_get_raw_time(ptp);
Expand All @@ -124,7 +136,7 @@ static void ptp_calculate_coefficient(struct mt_ptp_impl* ptp, int64_t delta) {
ptp->coefficient_result_min = RTE_MIN(coefficient, ptp->coefficient_result_min);
ptp->coefficient_result_max = RTE_MAX(coefficient, ptp->coefficient_result_max);
ptp->coefficient_result_cnt++;
if (ptp->coefficient - 1.0 < 1e-9) /* store first result */
if (ptp->coefficient - 1.0 < 1e-15) /* store first result */
ptp->coefficient = coefficient;
if (ptp->coefficient_result_cnt == 10) {
/* get every 10 results' average */
Expand Down Expand Up @@ -266,7 +278,15 @@ static int ptp_parse_result(struct mt_ptp_impl* ptp) {
}
ptp->delta_result_err = 0;

ptp_calculate_coefficient(ptp, delta);
if (ptp->use_pi && labs(correct_delta) < 1000) {
/* fine tune coefficient */
ptp_update_coefficient(ptp, correct_delta);
ptp->last_sync_ts = ptp_get_raw_time(ptp) + delta; /* approximation */
} else {
/* re-calculate coefficient */
ptp_calculate_coefficient(ptp, delta);
}

ptp_adjust_delta(ptp, delta);
ptp_t_result_clear(ptp);

Expand Down Expand Up @@ -655,7 +675,11 @@ static int ptp_init(struct mtl_main_impl* impl, struct mt_ptp_impl* ptp,
ptp->master_initialized = false;
ptp->t3_sequence_id = 0x1000 * port;
ptp->coefficient = 1.0;
ptp_coeffcient_result_reset(ptp);
ptp->kp = impl->user_para.kp < 1e-15 ? MT_PTP_DEFAULT_KP : impl->user_para.kp;
ptp->ki = impl->user_para.ki < 1e-15 ? MT_PTP_DEFAULT_KI : impl->user_para.ki;
ptp->use_pi = (impl->user_para.flags & MTL_FLAG_PTP_PI);
if (ptp->use_pi)
info("%s(%d), use pi controller, kp %e, ki %e\n", __func__, port, ptp->kp, ptp->ki);

struct mtl_init_params* p = mt_get_user_params(impl);
if (p->flags & MTL_FLAG_PTP_UNICAST_ADDR) {
Expand All @@ -666,6 +690,7 @@ static int ptp_init(struct mtl_main_impl* impl, struct mt_ptp_impl* ptp,
}

ptp_stat_clear(ptp);
ptp_coeffcient_result_reset(ptp);

if (!mt_if_has_ptp(impl, port)) {
if (mt_has_ebu(impl)) {
Expand Down

0 comments on commit 8bdf8a0

Please sign in to comment.