From 39e6bd8b1f5cd8fa1c30963a19d9a39ea609820a Mon Sep 17 00:00:00 2001 From: andreas128 Date: Mon, 25 Sep 2017 18:24:22 +0200 Subject: Add documentation to README.md --- dpd/README.md | 76 +- dpd/apply_adapt_dumps.py | 1 - dpd/doc/img/setup_diagram.pdf | Bin 26573 -> 0 bytes dpd/doc/img/setup_photo.pdf | Bin 2615291 -> 0 bytes dpd/doc/img/setup_photo.svg | 45958 -------------------------- dpd/doc/img/shoulder_measurement_after.png | Bin 1082203 -> 0 bytes dpd/doc/img/shoulder_measurement_before.png | Bin 1120718 -> 0 bytes dpd/img/setup_diagram.svg | 2 + dpd/img/setup_photo.svg | 184 + dpd/img/shoulder_measurement_after.png | Bin 0 -> 368619 bytes dpd/img/shoulder_measurement_before.png | Bin 0 -> 381174 bytes dpd/main.py | 2 +- dpd/src/Measure_Shoulders.py | 2 +- dpd/src/const.py | 2 +- 14 files changed, 264 insertions(+), 45963 deletions(-) delete mode 100644 dpd/doc/img/setup_diagram.pdf delete mode 100644 dpd/doc/img/setup_photo.pdf delete mode 100644 dpd/doc/img/setup_photo.svg delete mode 100644 dpd/doc/img/shoulder_measurement_after.png delete mode 100644 dpd/doc/img/shoulder_measurement_before.png create mode 100644 dpd/img/setup_diagram.svg create mode 100644 dpd/img/setup_photo.svg create mode 100644 dpd/img/shoulder_measurement_after.png create mode 100644 dpd/img/shoulder_measurement_before.png diff --git a/dpd/README.md b/dpd/README.md index 83a2986..d0049c4 100644 --- a/dpd/README.md +++ b/dpd/README.md @@ -1,7 +1,8 @@ Digital Predistortion Calculation Engine for ODR-DabMod ======================================================= -This folder contains work in progress for digital predistortion. +This folder contains a prototype to do digital predistortion. It was tested on +the development system only. Concept ------- @@ -39,6 +40,79 @@ 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](doc/img/setup_diagram.svg) +![setup photo](doc/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. Filter (190-250MHz, -3.5dB) + 3. Power amplifier (max +15dBm, +10 dB) + 4. Directional coupler (approx. -25dB @ 223MHz) + 5. Attenuator (-20 dB) + 6. Attenuator (-30 dB) + 7. USRP RX (max -15dBm) + 8. Spectrum analyzer (max +30dBm) + +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 pre-distortion software will later automatically apply a normalization for the RX input by adapting the USRP RX gain. + + +![P_{TX} + P_{PA} - P_{SP} - P_{AT} = 20dBm + 10dB -25dB -50dB = -45dBm](http://www.sciweavers.org/tex2img.php?eq=P_%7BTX%7D+%2B+P_%7BPA%7D+-+P_%7BSP%7D+-+P_%7BAT%7D+%3D+20dBm+%2B+10dB+-25dB+-50dB+%3D+-45dBm&bc=White&fc=Black&im=jpg&fs=12&ff=arev&edit=) + +Thus we have a margin of about 30dB for the input power of the USRP RX port. + + +Software Setup +-------------- + +We assume that you already installed *ODR-DabMux* and *ODR-DabMod*. In order to satisfy dependencies for the pre-distortion, you can install all required python modules using conda. Alternatively you can also install the packages specified in the environment file via your preferred method. To install and use the environment via conda do following: + +``` +conda env create -f dpd/environment.yml +source activate dab +``` + +Use the pre-distortion +---------------------- + +Run the multiplexer and the modulator: + +``` +ODR-DabMux/src/odr-dabmux ../simple.mux +ODR-DabMod/odr-dabmod dpd/dpd.ini +``` + +The script uses automatic gain control for both TX and RX gain, to get both a high quantization quality for the most frequent amplitude regions and a high enough back-off so the peaks are also quantized correctly. This means that the output power will stay at the same level, but the script may change TX gain to trade it with digital gain and also change RX gain. + +As a first test you can run the main script without parameters. It preserves the output power and generates all available visualization plots in the newly created logging directory `/tmp/dpd_`. To run it do following: + +``` +cd dpd +python main.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 the settings for the pre-distortion. To load them again without further measurements, you can use `apply_adapt_dumps.py`. + - MER: Constellation diagram used to calculate the modulation error rate. + +After the run you should be able to observe that the peak-shoulder difference decrease on your spectrum analyzer, similar to Figure below. + +Before digital predistortion: + +![shoulder_measurement_before](doc/img/shoulder_measurement_after.png) + +After digital predistortion: + +![shoulder_measurement_after](doc/img/shoulder_measurement_after.png) + +Now see what happens if you apply the pre-distortions for different TX gains. You can either set the TX gain before you start the pre-distortion 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 diff --git a/dpd/apply_adapt_dumps.py b/dpd/apply_adapt_dumps.py index 1d91717..7b661c9 100755 --- a/dpd/apply_adapt_dumps.py +++ b/dpd/apply_adapt_dumps.py @@ -156,7 +156,6 @@ tx_agc = TX_Agc.TX_Agc(adapt, c) agc = Agc.Agc(meas, adapt, c) agc.run() -import os paths = natsort.natsorted(glob.glob(searchpath + "/*.pkl")) print(paths) diff --git a/dpd/doc/img/setup_diagram.pdf b/dpd/doc/img/setup_diagram.pdf deleted file mode 100644 index d7d6cbb..0000000 Binary files a/dpd/doc/img/setup_diagram.pdf and /dev/null differ diff --git a/dpd/doc/img/setup_photo.pdf b/dpd/doc/img/setup_photo.pdf deleted file mode 100644 index 628534a..0000000 Binary files a/dpd/doc/img/setup_photo.pdf and /dev/null differ diff --git a/dpd/doc/img/setup_photo.svg b/dpd/doc/img/setup_photo.svg deleted file mode 100644 index 9f696f6..0000000 --- a/dpd/doc/img/setup_photo.svg +++ /dev/null @@ -1,45958 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - ⑤⑥ - - - diff --git a/dpd/doc/img/shoulder_measurement_after.png b/dpd/doc/img/shoulder_measurement_after.png deleted file mode 100644 index 62b75e4..0000000 Binary files a/dpd/doc/img/shoulder_measurement_after.png and /dev/null differ diff --git a/dpd/doc/img/shoulder_measurement_before.png b/dpd/doc/img/shoulder_measurement_before.png deleted file mode 100644 index 8756b11..0000000 Binary files a/dpd/doc/img/shoulder_measurement_before.png and /dev/null differ diff --git a/dpd/img/setup_diagram.svg b/dpd/img/setup_diagram.svg new file mode 100644 index 0000000..8833418 --- /dev/null +++ b/dpd/img/setup_diagram.svg @@ -0,0 +1,2 @@ + +
① USRP TX
① USRP TX
② Filter
② Filter
③ PA
③ PA
④ Dir. Coupler
④ Dir. Coupler
⑤,⑥ Attenuators
⑤,⑥ Attenuators
⑦ USRP RX
⑦ USRP RX
⑧ Spectrum Analyzer
⑧ Spectrum Analyzer
\ No newline at end of file diff --git a/dpd/img/setup_photo.svg b/dpd/img/setup_photo.svg new file mode 100644 index 0000000..a401fda --- /dev/null +++ b/dpd/img/setup_photo.svg @@ -0,0 +1,184 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + ⑤⑥ + + + diff --git a/dpd/img/shoulder_measurement_after.png b/dpd/img/shoulder_measurement_after.png new file mode 100644 index 0000000..2631256 Binary files /dev/null and b/dpd/img/shoulder_measurement_after.png differ diff --git a/dpd/img/shoulder_measurement_before.png b/dpd/img/shoulder_measurement_before.png new file mode 100644 index 0000000..3581a72 Binary files /dev/null and b/dpd/img/shoulder_measurement_before.png differ diff --git a/dpd/main.py b/dpd/main.py index c9bf0ba..871a404 100755 --- a/dpd/main.py +++ b/dpd/main.py @@ -206,7 +206,7 @@ while i < num_iter: off = SA.calc_offset(txframe_aligned) tx_mer = MER.calc_mer(txframe_aligned[off:off+c.T_U], debug=True, debug_name="TX") - rx_mer = MER.calc_mer(rxframe_aligned[off:off+c.T_U], debug=True, deubg_name="RX") + rx_mer = MER.calc_mer(rxframe_aligned[off:off+c.T_U], debug=True, debug_name="RX") mse = np.mean(np.abs((txframe_aligned - rxframe_aligned)**2)) tx_gain = adapt.get_txgain() rx_gain = adapt.get_rxgain() diff --git a/dpd/src/Measure_Shoulders.py b/dpd/src/Measure_Shoulders.py index 7a165c4..1417613 100644 --- a/dpd/src/Measure_Shoulders.py +++ b/dpd/src/Measure_Shoulders.py @@ -75,7 +75,7 @@ class Measure_Shoulder: dt = datetime.datetime.now().isoformat() fig_path = logging_path + "/" + dt + "_sync_subsample_aligned.svg" - fft = self.calc_fft_db(signal, 100) + fft = calc_fft_db(signal, 100) peak, idxs_peak = self._calc_peak(fft) shoulder, idxs_sh = self._calc_shoulder_hight(fft, self.c) diff --git a/dpd/src/const.py b/dpd/src/const.py index 6b0178f..cbef8af 100644 --- a/dpd/src/const.py +++ b/dpd/src/const.py @@ -45,7 +45,7 @@ class const: # Constants for TX_Agc self.TAGC_max_txgain = 89 - self.TAGC_tx_median_target = 0.1 + self.TAGC_tx_median_target = target_median self.TAGC_tx_median_max = self.TAGC_tx_median_target*1.4 self.TAGC_tx_median_min = self.TAGC_tx_median_target/1.4 -- cgit v1.2.3