SynchroPMU
C implementation of the Phasor Measurement Unit Estimator based on the Iterative Interpolated DFT Synchrophasor Estimation Algorithm
Loading...
Searching...
No Matches
pmu_estimator.c File Reference

Implementation of the PMU estimator based on the Iterative Enhanced Interpolated DFT Algorithm. More...

#include <stdio.h>
#include <complex.h>
#include <math.h>
#include <stdlib.h>
#include "iniparser.h"
#include "pmu_estimator.h"
Include dependency graph for pmu_estimator.c:

Macros

#define NUM_CHANLS   1
 Number of channels to process (can be defined at compile time)
 
#define DEBUG   3
 Debug logging level - includes all messages.
 
#define INFO   2
 Info logging level - includes info and error messages.
 
#define ERROR   1
 Error logging level - only error messages.
 
#define LOGGING_LEVEL   ERROR
 Current logging level (can be defined at compile time)
 
#define error(...)   fprintf(stderr, __VA_ARGS__)
 Error logging macro - outputs to stderr.
 
#define info(...)
 Info logging macro - outputs to stdout.
 
#define debug(...)
 Debug logging macro - outputs to stdout.
 
#define debug_bins(...)
 
#define wrap_angle(rad)   (((float_p)(rad) - 2 * M_PI_p * rint((float_p)(rad) / (2 * M_PI_p))))
 Wraps an angle to the range [-π, π] radians.
 
#define sineasin(x)   (pmue_sin(M_PI_p * (x)) / pmue_sin(ctx->hann_params.C4 * M_PI_p * (x)))
 Sine-over-sine ratio used in Hanning window DFT.
 
#define whDFT(x)   (pmue_cexp(-I * M_PI_p * ctx->hann_params.C3 * (x)) * (ctx->hann_params.C5 * sineasin((x) - 1) + ctx->hann_params.C1 * sineasin((x)) + ctx->hann_params.C6 * sineasin((x) + 1)))
 Hanning window DFT formula.
 
#define wf(k, f, in_phsr)   ((in_phsr) * whDFT((k) - ((f) / ctx->synch_params.df)) * (ctx->hann_params.inv_norm_factor))
 Weighted frequency bin calculation.
 

Functions

int pmu_init (pmu_context *ctx, void *cfg, bool_p config_from_ini)
 Initialize a PMU estimator instance.
 
int pmu_estimate (pmu_context *ctx, float_p *in_signal_windows, float_p mid_fracsec, pmu_frame *out_frame)
 Estimate synchrophasor, frequency, and ROCOF from input signal.
 
int pmu_deinit (pmu_context *ctx)
 Deinitialize and free resources of PMU estimator instance.
 
int pmu_dump_frame (pmu_frame *frame, FILE *stream)
 Print PMU frame data to output stream.
 

Detailed Description

Implementation of the PMU estimator based on the Iterative Enhanced Interpolated DFT Algorithm.

This file contains the complete implementation of a Phasor Measurement Unit (PMU) estimator that uses advanced signal processing techniques to accurately estimate synchrophasors, frequency, and Rate of Change of Frequency (ROCOF) from power system signals.

Algorithm Overview

The implementation uses the Iterative Enhanced Interpolated DFT (Discrete Fourier Transform) algorithm with the following key features:

  • Hanning Window: Applied to reduce spectral leakage
  • Interpolated DFT (ipDFT): Improves frequency resolution beyond FFT bin spacing
  • Enhanced ipDFT (e-ipDFT): Compensates for interference from nearby frequency components
  • Iterative Refinement: Multiple iterations improve accuracy under dynamic conditions
  • ROCOF Estimation: Calculates the rate of frequency change with low-pass filtering

Key Features

  • Multi-channel signal processing (configurable via NUM_CHANLS)
  • Configurable via INI file or structure
  • M-Class and P-Class PMU configurations supported
  • Optimized FFT for power-of-2 window sizes
  • Comprehensive logging system (ERROR, INFO, DEBUG levels)
  • Memory-efficient with dynamic allocation
Author
Chemseddine Allioua, Brahim Mazighi
Version
1.7.0

Macro Definition Documentation

◆ DEBUG

#define DEBUG   3

Debug logging level - includes all messages.

◆ debug

#define debug ( ...)

Debug logging macro - outputs to stdout.

◆ debug_bins

#define debug_bins ( ...)

◆ ERROR

#define ERROR   1

Error logging level - only error messages.

◆ error

#define error ( ...)    fprintf(stderr, __VA_ARGS__)

Error logging macro - outputs to stderr.

◆ INFO

#define INFO   2

Info logging level - includes info and error messages.

◆ info

#define info ( ...)

Info logging macro - outputs to stdout.

◆ LOGGING_LEVEL

#define LOGGING_LEVEL   ERROR

Current logging level (can be defined at compile time)

◆ NUM_CHANLS

#define NUM_CHANLS   1

Number of channels to process (can be defined at compile time)

◆ sineasin

#define sineasin ( x)    (pmue_sin(M_PI_p * (x)) / pmue_sin(ctx->hann_params.C4 * M_PI_p * (x)))

Sine-over-sine ratio used in Hanning window DFT.

◆ wf

#define wf ( k,
f,
in_phsr )   ((in_phsr) * whDFT((k) - ((f) / ctx->synch_params.df)) * (ctx->hann_params.inv_norm_factor))

Weighted frequency bin calculation.

◆ whDFT

#define whDFT ( x)    (pmue_cexp(-I * M_PI_p * ctx->hann_params.C3 * (x)) * (ctx->hann_params.C5 * sineasin((x) - 1) + ctx->hann_params.C1 * sineasin((x)) + ctx->hann_params.C6 * sineasin((x) + 1)))

Hanning window DFT formula.

◆ wrap_angle

#define wrap_angle ( rad)    (((float_p)(rad) - 2 * M_PI_p * rint((float_p)(rad) / (2 * M_PI_p))))

Wraps an angle to the range [-π, π] radians.

Function Documentation

◆ pmu_deinit()

int pmu_deinit ( pmu_context * ctx)

Deinitialize and free resources of PMU estimator instance.

Releases all dynamically allocated memory associated with the PMU context and resets the initialization flag. After calling this function, the context can be reinitialized with pmu_init() if needed.

Parameters
[in,out]ctxPointer to the PMU context to deinitialize
Returns
0 on success, -1 on error
Note
Always call this function when finished with a PMU context to prevent memory leaks.
See also
pmu_init()

◆ pmu_dump_frame()

int pmu_dump_frame ( pmu_frame * frame,
FILE * stream )

Print PMU frame data to output stream.

Outputs the contents of a pmu_frame structure in a human-readable format to the specified output stream (e.g., stdout, stderr, or a file).

Parameters
[in]framePointer to the PMU frame to dump
[in]streamOutput stream (e.g., stdout, stderr, or FILE pointer from fopen)
Returns
0 on success, -1 on error
See also
pmu_frame

◆ pmu_estimate()

int pmu_estimate ( pmu_context * ctx,
float_p * in_signal_windows,
float_p mid_fracsec,
pmu_frame * out_frame )

Estimate synchrophasor, frequency, and ROCOF from input signal.

This is the main estimation function that processes a window of input samples and produces synchrophasor and ROCOF estimates using the Iterative Enhanced Interpolated DFT algorithm.

Parameters
[in]ctxPointer to initialized PMU context
[in]in_signal_windowsPointer to input signal samples. For multi-channel: array of pointers to signal windows for each channel. Array size must match NUM_CHANLS configuration.
[in]mid_fracsecFractional second timestamp (relative to PPS) of the midpoint of the observation window. Used for phase correction.
[out]out_framePointer to output PMU frame structure where results are stored
Returns
0 on success, -1 on error
Warning
The size of in_signal_windows must match the NUM_CHANLS setting used during compilation. Mismatch will cause segmentation fault.
Note
The context must be initialized with pmu_init() before calling this function.
See also
pmu_init()
pmu_frame

◆ pmu_init()

int pmu_init ( pmu_context * ctx,
void * cfg,
bool_p config_from_ini )

Initialize a PMU estimator instance.

Initializes a PMU estimator context with the specified configuration. The configuration can be loaded from an INI file or passed as a structure.

Parameters
[in,out]ctxPointer to the PMU context structure to initialize
[in]cfgConfiguration: either a filename (char*) if config_from_ini=1, or a pointer to an estimator_config structure if config_from_ini=0
[in]config_from_iniConfiguration source flag:
  • CONFIG_FROM_INI (1): Load from INI file
  • CONFIG_FROM_STRUCT (0): Use structure
Returns
0 on success, -1 on error
Note
The context should not be already initialized. Call pmu_deinit() first if reinitializing an existing context.
See also
pmu_deinit()
estimator_config