After three months of great learning and working experience through GSoC 2020 with GNU Radio, I feel obliged to thank everyone directly or indirectly involved in helping me from the very first contributions in GNU Radio to getting in as a GSoC student this year.
Final week’s work
Most of work involved manually re-doing and commiting the changes from other branch (synchronisation_test) and testing the working of predistorter (static mode) using a verified combination of PA model coefficients and DPD coefficients extracted using some external Input and PA output (without DPD) data and a MATLAB script.
Major commits to the gr-dpd repository are:
- Synchronised passing of ‘taps’: These changes involve the blocks namely predistorter, RLS and LMS postdistorters to achieve some sort of improvement in performance and synchronisation in message passing of ‘taps‘ in between predistorter and postdistorter in turn doing correct estimation of coefficients. These changes were already present on synchronisation_test branch waiting testing approval. For more details see here.
- Added Data files in examples folder: It contains following data extracted using an external MATLAB script and some already present data:
- Added verified corresponding PA model coefficients and DPD coefficients and a CPP code generate a complex_vector using real and imag. data files.
- Added Input data files consisting imag., real data(.txt) files and binary format (BIN) file.
- Added Predistorter output data files consisting imag., real data(.txt) files and binary format (BIN) file for corresponding coeffs. and Input data.
- Added PA output (without DPD) data files consisting imag., real data(.txt) files and binary format (BIN) file.
- Added DPD output or PA output (with DPD) data files consisting imag., real data(.txt) files and binary format (BIN) file.
- Eliminate bug in predistorter & GMP model: It removes the error in GMP vector generation for value of K_b is zero. Another error in predistorter was removed by using the correct transpose of GMP vector generated by using st() instead of t() function of armadillo library.
- Added Static_Predistorter_iq_data_file test flowgraph: This flowgraph tests the working of predistorter (static mode) and GMP model PA for the extracted corrresponding values of coefficients for both DPD and PA model. It uses precomputed output data files plots to verify the proper working of blocks.
- Added RLS_iq_test flowgraph: This flowgraph tests the working & performance of RLS_postdistorter for Input data(BIN) file source.
Above figure (obtained on running Static_Predistorter_iq_data_file test flowgraph) clearly justifies the proper functioning of Static Predistorter for precomputed PA and DPD coefficients based on MP model as GNU Radio DPD plot (using the predistorter and GMP model blocks) is almost identical to the Data files plot (using file sources of precomputed output data).
Above plot (obtained on running RLS_iq_test flowgraph) justifies some good results of predistortion as reduction in sidebands or distortion is visible for when comparing PA_DPD against PA_without_DPD.
In above two figures:
- Input refers to the input signal through file source using stored binary Input file.
- PA_without_DPD refers to the Power Amplifier Output for corrsponding input without using any Digital Pre-Distortion.
- Predistorter_out refers to the output of predistorter for corresponding input. And then predistorter output is input to the Power Amplifier.
- PA_DPD refers to the Power Amplifier Output using predistorter output as input or using Digital Pre-Distortion.
This GSoC Project titled “gr-dpd: Digital Pre-Distortion” was developed with aim of implementing Digital Pre-Distortion, in form of C++ blocks available for use within GRC, within a separate OOT (out-of-tree) module namely, gr-dpd.
The predistorter block performing the predistortion using ‘taps‘ or weights/ coefficients vector has been provided with two modes of operation, namely Static and Training mode.
For Static mode, predistortion coefficients vector or ‘taps’ are provided as a block parameter during initialisation.
While, for this purpose following training algorithms have been implemented and added to the module in form of blocks:
- RLS (Recursive Least Squares) Based Adaptive Algorithm
- LMS (Least Means Squares) Based Adaptive Algorithm.
Below are the milestones achieved during this summer project:
- Create the gr-dpd OOT module, initial directory structure using gr_modtool.
- Implement GMP and MP model PA (Power Amplifier) blocks using Generalised Memory Polynomial and Memory Polynomial for computing output for corresponding inputs.
- Add C++ code for both GMP and MP model blocks, their processing and YAML files for both GMP and MP model blocks for GRC binding.
- Implement stream_to_gmp_vector and stream_to_message blocks.
- Add C++ code for both stream to gmp_vector and message blocks, their processing and YAML files for both stream to gmp_vector and message blocks for GRC binding.
- Later on, use of these two blocks was eliminated on shifting to stream ports than message ports and doing intrinsic GMP vector generation within predistorter itself.
- Implement predistorter_training block to performance predistortion using the ‘taps’ or predistortion coefficients supplied to the it, either by Static or Training mode. Or in simple words, perform multiplication of row GMP vector for each input with the column ‘taps’ vector, producing predistorted output.
- Add C++ code for the block in gr-dpd and YAML file making it available in GRC.
- At first, predistorter was implemented keeping in mind only the training algorithm, by default receiving weights vector only through the message port ‘taps’.
- Later on, the option of Static mode in which user can provide the precomputed DPD coefficients for a PA directly as a complex_vector block parameter added.
- Add Static_Predistorter test flowgraph to demonstrate the use of predistorter in Static mode.
- Implement gain_phase_calibrate block to remove the gain phase from the PA output to calibrate it for error calculation for adaptive coefficient estimation.
- Add C++ code for the block in gr-dpd and YAML file making it available in GRC.
- Later on, improved it by introducing another input port ‘PA_DPD’ to control which value to be multiplied by calibration factor (inverse gain) calculated using the input and output sample values, to produce calibrated output.
- Add gain_phase_test and gain_phase_GMP_test flowgraphs to test and ensure proper working of the block.
- Implement RLS based training algorithm to perform adaptive coefficient estimation for predistortion, using Hyperbolics and Givens Rotation.
- Add C++ Prototype Code demonstrating RLS algorithm’s mathematical computations involved in ‘taps’ updation/estimation and reduction in the error for new ‘taps’.
- Add C++ code for RLS_postdistorter block and YAML file to make it available in GRC.
- Add RLS_test_run_single_tone and RLS_test_run_two_tone_setup flowgraph examples to get a test of the running of algorithm on basic tones and a basic idea of the degree of correctness in the performance of adaptive postdistortion implemented with help of GNU Radio blocks.
- Implement LMS based training algorithm to perform adaptive coefficient estimation for predistortion based on solving linear equation.
- Add C++ Prototype Code demonstrating its mathematical computations involved in ‘taps’ estimation and reduction in the error for new ‘taps’. It has two options for mode of operation, namely, Newton and EMA, denoting the method for updating weights vector.
- Add C++ code for LMS_postdistorter block and YAML file to make it available in GRC.
- Add LMS _test_run_two_setup flowgraph example to get a test of the running of the algorithm on basic tones and a basic idea of the degree of correctness in the performance of adaptive postdistortion implemented with help of GNU Radio blocks.
- Get a verified set of PA and DPD model coefficients extracted using some Input and PA output data.
- Add a short C++ code snippet used to get a complex_vector of Coefficients from separate real and imag. data files in format suitable for GRC block parameter.
- Add Input data, PA_output (without DPD) data, Pre_output (Predistorter output) data and DPD_output (PA output with DPD) data files.
- Add extracted pa_coeff and dpd_coeff (.txt)files.
- Add final description/ documentation of gr-dpd blocks.
So, I was able to get the gr-dpd available with two learning algorithms namely, RLS and LMS based, a static mode of predistortion increasing flexibility of use of this module and two PA models, i.e., MP and GMP. However, further testing and modifications are still required to get near perfect results from DPD training blocks. Another algorithm based on Look Up Table can be future addition to this module. After proper testing (by many developers) & a close review of this OOT module and considering its impact on the core GNU Radio toolkit, it can be considered to be added into the source tree (or maybe some of its blocks).
Apart from great technical learnings, GSoC 2020 with GNU Radio proved to be an experience of dealing with uncertainities and sweet results sometimes. It was a memorable learning experience with my mentors Derek Kozel, Andrej Rode and Zack Costello and I would like to thank them from the bottom of my heart for constant support and motivation provided alongwith technical lessons.
I look forward to continue contributing to the GNU Radio project and further development of gr-dpd to get it into the core or atleast ready and tested for practical applications.