aboutsummaryrefslogtreecommitdiffstats
path: root/python/dpd/README.md
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2018-12-04 10:18:33 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-12-04 10:18:33 +0100
commitd5cbe10c0e2298b0e40161607a3da158249bdb82 (patch)
tree5f6a0ff40ce5b3dd39d0df1c348557b183b48a7e /python/dpd/README.md
parent594cb2691debaa7562fd7d76d3b224701ec087ea (diff)
downloaddabmod-d5cbe10c0e2298b0e40161607a3da158249bdb82.tar.gz
dabmod-d5cbe10c0e2298b0e40161607a3da158249bdb82.tar.bz2
dabmod-d5cbe10c0e2298b0e40161607a3da158249bdb82.zip
Move python stuff to folder
Diffstat (limited to 'python/dpd/README.md')
-rw-r--r--python/dpd/README.md264
1 files changed, 264 insertions, 0 deletions
diff --git a/python/dpd/README.md b/python/dpd/README.md
new file mode 100644
index 0000000..307a2f5
--- /dev/null
+++ b/python/dpd/README.md
@@ -0,0 +1,264 @@
+Digital Predistortion Computation Engine for ODR-DabMod
+=======================================================
+
+This folder contains a digital predistortion prototype.
+It was only tested in a laboratory system, and is not ready
+for production usage.
+
+Concept
+-------
+
+ODR-DabMod makes outgoing TX samples and feedback RX samples available to an
+external tool. This external tool can request a buffer of samples for analysis,
+can calculate coefficients for the predistorter in ODR-DabMod and load the new
+coefficients using the remote control.
+
+The external tool is called the Digital Predistortion Computation Engine (DPDCE).
+The DPDCE is written in python, and makes use of the numpy library for
+efficient computation. Its sources reside in the *dpd* folder.
+
+The predistorter in ODR-DabMod supports two modes: polynomial and lookup table.
+In the DPDCE, only the polynomial model is implemented at the moment.
+
+The *dpd/main.py* script is the entry point for the *DPD Computation Engine*
+into which these features will be implemented. The tool uses modules from the
+*dpd/src/* folder:
+
+- Sample transfer and time alignment with subsample accuracy is done by *Measure.py*
+- Estimating the effects of the PA using some model and calculation of the updated
+ polynomial coefficients is done in *Model.py* and other specific *Model_XXX.py* files
+- Finally, *Adapt.py* updates the ODR-DabMod predistortion setting and digital gain
+
+These modules themselves use additional helper scripts in the *dpd/src/* folder.
+
+Requirements
+------------
+
+- USRP B200.
+- Power amplifier.
+- A feedback connection from the power amplifier output, such that the average power level at
+ the USRP RX port is at -45dBm or lower.
+ Usually this is done with a directional coupler and additional attenuators.
+- ODR-DabMod with enabled *dpd_port*, and with a samplerate of 8192000 samples per second.
+- Synchronous=1 so that the USRP has the timestamping set properly, internal refclk and pps
+ are sufficient (not GPSDO necessary).
+- A live mux source with TIST enabled.
+
+See dpd/dpd.ini for an example.
+
+The DPD server port can be tested with the *dpd/show_spectrum.py* helper tool, which can also display
+a constellation diagram.
+
+Hardware Setup
+--------------
+
+![setup diagram](img/setup_diagram.svg)
+![setup photo](img/setup_photo.svg)
+
+Our setup is depicted in the Figure above. We used components with the following properties:
+ 1. USRP TX (max +20dBm)
+ 2. Band III Filter (Mini-Circuits RBP-220W+, 190-250MHz, -3.5dB)
+ 3. Power amplifier (Mini-Circuits, max +15dBm output, +10 dB gain at 200MHz)
+ 4. Directional coupler (approx. -25dB @ 223MHz)
+ 5. Attenuator (-20 dB)
+ 6. Attenuator (-30 dB)
+ 7. USRP RX (max -15dBm input allowed, max -45dBm desired)
+ 8. Spectrum analyzer (max +30dBm allowed)
+
+It is important to make sure that the USRP RX port does not receive too much
+power. Otherwise the USRP will break. Here is an example of how we calculated
+the maximal USRP RX input power for our case. As this is only a rough
+calculation to protect the port, the predistortion software will later
+automatically apply a normalization for the RX input by adapting the USRP RX
+gain.
+
+ TX Power + PA Gain - Coupling Factor - Attenuation = 20dBm + 10dB -25dB -50dB = -45dBm
+
+Thus we have a margin of about 30dB for the input power of the USRP RX port.
+Keep in mind we need to calculate using peak power, not average power, and it is
+essential that there is no nonlinearity in the RX path!
+
+Software Setup
+--------------
+
+We assume that you already installed *ODR-DabMux* and *ODR-DabMod*.
+You should install the required python dependencies for the DPDCE using
+distribution packages. You will need at least scipy, matplotlib and
+python-zeromq.
+
+Use the predistortion
+----------------------
+
+Make sure you have a ODR-DabMux running with a TCP output on port 9200.
+
+Then run the modulator, with the example dpd configuration file.
+
+```
+./odr-dabmod dpd/dpd.ini
+```
+
+This configuration file is different from usual defaults in several respects:
+
+ * logging to /tmp/dabmod.log
+ * 4x oversampling: 8192000 sample rate
+ * a very small digital gain, which will be overridden by the DPDCE
+ * predistorter enabled
+
+The TX gain should be chosen so that you can drive your amplifier into
+saturation with a digital gain of 0.1, so that there is margin for the DPD to
+operate.
+
+You should *not modify txgain, rxgain, digital gain or coefficient settings manually!*
+When the DPDCE is used, it controls these settings, and there are command line
+options for you to define initial values.
+
+To verify that the communication between the DPDCE and ODR-DabMod is ok,
+you can use the status and reset options:
+
+```
+cd dpd
+python main.py --status
+python main.py --reset
+```
+
+The reset option sets all DPD-related settings to the defaults (as shown in the
+`--help` usage screen) and stops.
+
+When neither `--status` nor `--reset` is given, the DPDCE will run the predistortion
+algorithm. As a first test you should run the DPDCE with the `--plot`
+parameter. It preserves the output power and generates all available
+visualisation plots in the newly created logging directory
+`/tmp/dpd_<time_stamp>`. As the predistortion should increase the peak to
+shoulder ratio, you should select a *txgain* in the ODR-DabMod configuration
+file such that the initial peak-to-soulder ratio visible on your spectrum
+analyser. This way, you will be able to see a the
+change.
+
+```
+cd dpd
+python main.py --plot
+```
+
+The DPDCE now does 10 iterations, and tries to improve the predistortion effectiveness.
+In each step the learning rate is decreased. The learning rate is the factor
+with which new coefficients are weighted in a weighted mean with the old
+coefficients. Moreover the nuber of measurements increases in each iteration.
+You find more information about that in *Heuristic.py*.
+
+Each plot is stored to the logging directory under a filename containing its
+time stamp and its label. Following plots are generated chronologically:
+
+ - ExtractStatistic: Extracted information from one or multiple measurements.
+ - Model\_AM: Fitted function for the amplitudes of the power amplifier against the TX amplitude.
+ - Model\_PM: Fitted function for the phase difference of the power amplifier against the TX amplitude.
+ - adapt.pkl: Contains all settings for the predistortion.
+ You can load them again without doing measurements with the `apply_adapt_dumps.py` script.
+ - MER: Constellation diagram used to calculate the modulation error rate.
+
+After the run you should be able to observe that the peak-to-shoulder
+difference has increased on your spectrum analyzer, similar to the figure below.
+
+Without digital predistortion:
+
+![shoulder_measurement_before](img/shoulder_measurement_before.png)
+
+With digital predistortion, computed by the DPDCE:
+
+![shoulder_measurement_after](img/shoulder_measurement_after.png)
+
+Now see what happens if you apply the predistortions for different TX gains.
+You can either set the TX gain before you start the predistortion or using the
+command line option `--txgain gain`. You can also try to adjust other
+parameters. To see their documentation run `python main.py --help`.
+
+File format for coefficients
+----------------------------
+The coef file contains the polynomial coefficients used in the predistorter.
+The file format is very similar to the filtertaps file used in the FIR filter.
+It is a text-based format that can easily be inspected and edited in a text
+editor.
+
+The first line contains an integer that defines the predistorter to be used:
+1 for polynomial, 2 for lookup table.
+
+For the polynomial, the subsequent line contains the number of coefficients
+as an integer. The second and third lines contain the real, respectively the
+imaginary parts of the first coefficient. Fourth and fifth lines give the
+second coefficient, and so on. The file therefore contains 1 + 1 + 2xN lines if
+it contains N coefficients.
+
+For the lookup table, the subsequent line contains a float scalefactor that is
+applied to the samples in order to bring them into the range of 32-bit unsigned
+integer. Then, the next pair of lines contains real and imaginary part of the first
+lookup-table entry, which is multiplied to samples in first range. Then it's
+followed by 31 other pairs. The entries are complex values close to 1 + 0j.
+The file therefore contains 1 + 1 + 2xN lines if it contains N coefficients.
+
+TODO
+----
+
+ - Understand and fix occasional ODR-DabMod crashes when using DPDCE.
+ - Make the predistortion more robust. At the moment the shoulders sometimes
+ increase instead of decrease after applying newly calculated predistortion
+ parameters. Can this behaviour be predicted from the measurement? This would
+ make it possible to filter out bad predistortion settings.
+ - Find a better measurement for the quality of the predistortion. The USRP
+ might not be good enough to measure large peak-to-shoulder ratios, because
+ the ADC has 12 bits and DAB signals have a large crest factor.
+ - Implement a Volterra polynomial to model the PA. Compared to the current
+ model this would also capture the time dependent behaviour of the PA (memory
+ effects).
+ - Continuously observe DAB signal in frequency domain and make sure the power
+ stays the same. At the moment only the power in the time domain is kept the
+ same.
+ - At the moment we assume that the USRP RX gain has to be larger than 30dB and
+ the received signal should have a median absolute value of 0.05 in order to
+ have a high quality quantization. Do measurements to support or improve
+ this heuristic.
+ - Check if we need to measure MER differently (average over more symbols?)
+ - Is -45dBm the best RX feedback power level?
+
+REFERENCES
+----------
+
+Some papers:
+
+The paper Raich, Qian, Zhou, "Orthogonal Polynomials for Power Amplifier
+Modeling and Predistorter Design" proposes other base polynomials that have
+less numerical instability.
+
+AladreĢn, Garcia, Carro, de Mingo, and Sanchez-Perez, "Digital Predistortion
+Based on Zernike Polynomial Functions for RF Nonlinear Power Amplifiers".
+
+Jiang and Wilford, "Digital predistortion for power amplifiers using separable functions"
+
+Changsoo Eun and Edward J. Powers, "A New Volterra Predistorter Based on the Indirect Learning Architecture"
+
+Raviv Raich, Hua Qian, and G. Tong Zhou, "Orthogonal Polynomials for Power Amplifier Modeling and Predistorter Design"
+
+
+Models without memory:
+
+Complex polynomial: y[i] = a1 x[i] + a2 x[i]^2 + a3 x[i]^3 + ...
+
+The complex polynomial corresponds to the input/output relationship that
+applies to the PA in passband (real-valued signal). According to several
+sources, this gets transformed to another representation if we consider complex
+baseband instead. In the following, all variables are complex.
+
+Odd-order baseband: y[i] = (b1 + b2 abs(x[i])^2 + b3 abs(x[i])^4) + ...) x[i]
+
+Complete baseband: y[i] = (b1 + b2 abs(x[i]) + b3 abs(x[i])^2) + ...) x[i]
+
+with
+ b_k = 2^{1-k} \binom{k}{(k-1)/2} a_k
+
+
+Models with memory:
+
+ - Hammerstein model: Nonlinearity followed by LTI filter
+ - Wiener model: LTI filter followed by NL
+ - Parallel Wiener: input goes to N delays, each delay goes to a NL, all NL outputs summed.
+
+Taken from slide 36 of [ECE218C Lecture 15](http://www.ece.ucsb.edu/Faculty/rodwell/Classes/ece218c/notes/Lecture15_Digital%20Predistortion_and_Future%20Challenges.pdf)
+