diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-12-05 12:12:45 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-12-05 12:12:45 +0100 |
commit | e749bd08958a462f57b8492721a04128468656d0 (patch) | |
tree | 1c3c7801ccc8985f7f4393daf8d275c5eed4a717 /python | |
parent | 31b65e41043900c0cadd80961f4b22cdfc171e7d (diff) | |
download | dabmod-e749bd08958a462f57b8492721a04128468656d0.tar.gz dabmod-e749bd08958a462f57b8492721a04128468656d0.tar.bz2 dabmod-e749bd08958a462f57b8492721a04128468656d0.zip |
Get calibration to work with GUI
Diffstat (limited to 'python')
-rw-r--r-- | python/dpd/Measure.py | 7 | ||||
-rw-r--r-- | python/dpd/RX_Agc.py | 5 | ||||
-rwxr-xr-x | python/dpdce.py | 38 | ||||
-rwxr-xr-x | python/gui/api.py | 3 | ||||
-rw-r--r-- | python/gui/static/js/odr-predistortion.js | 30 | ||||
-rw-r--r-- | python/gui/static/js/odr.js | 48 | ||||
-rw-r--r-- | python/gui/templates/predistortion.html | 19 |
7 files changed, 70 insertions, 80 deletions
diff --git a/python/dpd/Measure.py b/python/dpd/Measure.py index 36b1888..489c4c0 100644 --- a/python/dpd/Measure.py +++ b/python/dpd/Measure.py @@ -94,14 +94,15 @@ class Measure: def get_samples(self): """Connect to ODR-DabMod, retrieve TX and RX samples, load into numpy arrays, and return a tuple - (txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median) + (txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median) """ txframe, tx_ts, rxframe, rx_ts = self.receive_tcp() # Normalize received signal with sent signal rx_median = np.median(np.abs(rxframe)) - rxframe = rxframe / rx_median * np.median(np.abs(txframe)) + tx_median = np.median(np.abs(txframe)) + rxframe = rxframe / rx_median * tx_median du = DU.Dab_Util(self.c, self.samplerate) txframe_aligned, rxframe_aligned = du.subsample_align(txframe, rxframe) @@ -111,7 +112,7 @@ class Measure: % (len(txframe), txframe.dtype, len(rxframe), rxframe.dtype, len(txframe_aligned), txframe_aligned.dtype, len(rxframe_aligned), rxframe_aligned.dtype) ) - return txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median + return txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median # The MIT License (MIT) # diff --git a/python/dpd/RX_Agc.py b/python/dpd/RX_Agc.py index 2a2f548..48ef7f3 100644 --- a/python/dpd/RX_Agc.py +++ b/python/dpd/RX_Agc.py @@ -48,7 +48,7 @@ class Agc: self.adapt.set_rxgain(self.rxgain) # Measure - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median=self.measure.get_samples() + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = self.measure.get_samples() # Estimate Maximum rx_peak = self.peak_to_median * rx_median @@ -89,8 +89,7 @@ class Agc: axs = axs.ravel() for j in range(5): - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median =\ - self.measure.get_samples() + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = self.measure.get_samples() rxframe_aligned_abs = np.abs(rxframe_aligned) diff --git a/python/dpdce.py b/python/dpdce.py index efc69ef..838d265 100755 --- a/python/dpdce.py +++ b/python/dpdce.py @@ -137,8 +137,8 @@ settings = { results = { 'tx_median': 0, 'rx_median': 0, - 'state': 'idle', - 'summary': 'DPD has not been calibrated yet', + 'state': 'Idle', + 'summary': ['DPD has not been calibrated yet'], } lock = Lock() command_queue = Queue(maxsize=1) @@ -155,23 +155,23 @@ def engine_worker(): break elif cmd == "calibrate": with lock: - results['state'] = 'rx agc' + results['state'] = 'rx gain calibration' agc_success, agc_summary = agc.run() - summary = ["First calibration run: " + agc_summary] + summary = ["First calibration run:"] + agc_summary.split("\n") if agc_success: agc_success, agc_summary = agc.run() - summary.append("Second calibration run: " + agc_summary) + summary += ["Second calibration run: "] + agc_summary.split("\n") - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median = self.measure.get_samples() + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() with lock: settings['rx_gain'] = adapt.get_rxgain() settings['digital_gain'] = adapt.get_digital_gain() - results['tx_median'] = tx_median - results['rx_median'] = rx_median - results['state'] = 'idle' - results['summary'] = "Calibration was done:\n" + "\n".join(agc_summary) + results['tx_median'] = float(tx_median) + results['rx_median'] = float(rx_median) + results['state'] = 'Idle' + results['summary'] = ["Calibration was done:"] + summary finally: with lock: @@ -190,17 +190,21 @@ try: continue except TimeoutError: continue + except KeyboardInterrupt: + logging.info('Caught KeyboardInterrupt') + break except: logging.error('YAML-RPC unknown error') break - logging.info('YAML-RPC request : {}'.format(method)) - if method == 'trigger_run': + logging.info('YAML-RPC request : {}'.format(method)) command_queue.put('trigger_run') elif method == 'reset': + logging.info('YAML-RPC request : {}'.format(method)) command_queue.put('reset') elif method == 'set_setting': + logging.info('YAML-RPC request : {} -> {}'.format(method, params)) # params == {'setting': ..., 'value': ...} pass elif method == 'get_settings': @@ -210,20 +214,20 @@ try: with lock: cmd_socket.send_success_response(addr, msg_id, results) elif method == 'calibrate': + logging.info('YAML-RPC request : {}'.format(method)) command_queue.put('calibrate') - elif method == "get_calibration_result": - pass else: cmd_socket.send_error_response(addr, msg_id, "request not understood") finally: command_queue.put('quit') + logging.info('Waiting for DPDCE to stop') engine.join() # Make code below unreachable sys.exit(0) def measure_once(): - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median = meas.get_samples() + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() print("TX signal median {}".format(np.median(np.abs(txframe_aligned)))) print("RX signal median {}".format(rx_median)) @@ -255,7 +259,7 @@ while i < num_iter: # Measure if state == 'measure': # Get Samples and check gain - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median = meas.get_samples() + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() # TODO Check TX median # Extract usable data from measurement @@ -288,7 +292,7 @@ while i < num_iter: # Report elif state == 'report': try: - txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median = meas.get_samples() + txframe_aligned, tx_ts, rxframe_aligned, rx_ts, rx_median, tx_median = meas.get_samples() # Store all settings for pre-distortion, tx and rx adapt.dump() diff --git a/python/gui/api.py b/python/gui/api.py index 0d24bac..bff224e 100755 --- a/python/gui/api.py +++ b/python/gui/api.py @@ -134,5 +134,6 @@ class API: if cherrypy.request.method == 'POST': return self._wrap_dpd("calibrate") else: - return self._wrap_dpd("get_calibration_result") + cherrypy.response.status = 400 + return send_error("POST only") diff --git a/python/gui/static/js/odr-predistortion.js b/python/gui/static/js/odr-predistortion.js index b2f1d22..04d2773 100644 --- a/python/gui/static/js/odr-predistortion.js +++ b/python/gui/static/js/odr-predistortion.js @@ -20,7 +20,15 @@ function resultrefresh() { var jqxhr = doApiRequestGET("/api/dpd_results", function(data) { - $('#dpdresults').text(data['summary']); + var summary = ""; + console.log(data); + for (k in data['summary']) { + summary += data['summary'][k]; + summary += "<br />"; + } + $('#dpdresults').html(summary); + + $('#dpdstatus').text(data['state']); }); jqxhr.always(function() { @@ -30,6 +38,13 @@ function resultrefresh() { $(function(){ setTimeout(resultrefresh, 2000); + + $('#calibratebtn').click(function() { + doApiRequestPOST("/api/dpd_calibrate", {}, function(data) { + console.log("calibrate succeeded: " + JSON.stringify(data)); + }); + }); + }); /* @@ -47,7 +62,6 @@ function calibraterefresh() { } $(function(){ - $('#calibraterefreshbtn').click(calibraterefresh); $('#refreshframesbtn').click(function() { var d = new Date(); var n = d.getTime(); @@ -55,18 +69,6 @@ $(function(){ $('#rxframeimg').src = "dpd/rxframe.png?cachebreak=" + n; }); - $('#calibratebtn').click(function() { - doApiRequestPOST("/api/calibrate", {}, function(data) { - console.log("calibrate succeeded: " + JSON.stringify(data)); - - $('#calibrationresults').text("Processing..."); - - setTimeout(function() { - calibraterefresh(); - }, 3000); - }); - }); - $('#capturebutton').click(function() { doApiRequestPOST("/api/trigger_capture", {}, function(data) { console.log("trigger_capture succeeded: " + JSON.stringify(data)); diff --git a/python/gui/static/js/odr.js b/python/gui/static/js/odr.js index 0bf7729..50c321c 100644 --- a/python/gui/static/js/odr.js +++ b/python/gui/static/js/odr.js @@ -27,19 +27,14 @@ function doApiRequestGET(uri, callback) { dataType: 'json', error: function(data) { - if (data.status == 500) { - var errorWindow = window.open("", "_self"); - errorWindow.document.write(data.responseText); - } - else { - console.log(data.responseText); + console.log(data.responseText); - $.gritter.add({ title: 'API', - text: "AJAX failed: " + data.statusText, - image: '/fonts/warning.png', - sticky: true, - }); - } + $.gritter.add({ title: 'API', + text: "AJAX failed: " + data.statusText, + image: '/fonts/warning.png', + sticky: false, + time: 4000, + }); }, success: function(data) { if (data.status == 'ok') { @@ -50,7 +45,8 @@ function doApiRequestGET(uri, callback) { title: 'API', text: "API ERROR: " + data.reason, image: '/fonts/warning.png', - sticky: true, + sticky: false, + time: 4000, }); } } @@ -66,22 +62,15 @@ function doApiRequestPOST(uri, data, callback) { data: JSON.stringify(data), error: function(data) { - if (data.status == 500) { - var windowObjectReference; - var winFeatures = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes"; - var errorWindow = window.open("", "Error 500", winFeatures); - errorWindow.document.write(data.responseText); - } - else { - console.log(data.responseText); + console.log(data.responseText); - $.gritter.add({ - title: 'API', - text: "AJAX failed: " + data.statusText, - image: '/fonts/warning.png', - sticky: true, - }); - } + $.gritter.add({ + title: 'API', + text: "AJAX failed: " + data.statusText, + image: '/fonts/warning.png', + sticky: false, + time: 4000, + }); }, success: function(data_in) { @@ -93,7 +82,8 @@ function doApiRequestPOST(uri, data, callback) { title: 'API', text: "API ERROR: " + data_in.reason, image: '/fonts/warning.png', - sticky: true, + sticky: false, + time: 4000, }); } } diff --git a/python/gui/templates/predistortion.html b/python/gui/templates/predistortion.html index ac68537..cc5ecb0 100644 --- a/python/gui/templates/predistortion.html +++ b/python/gui/templates/predistortion.html @@ -29,27 +29,20 @@ along with ODR-DabMod. If not, see <http://www.gnu.org/licenses/>. <div class="container-fluid"> <div class="panel-group"> <div class="panel panel-default"> - <div class="panel-heading">Status</div> + <div class="panel-heading">Status and calibration</div> <div class="panel-body"> - <div>Current DPDCE status: - <div class="well well-sm" id="dpdresults">N/A<div> + <div>Current DPDCE status: <span id="dpdstatus" style="font-weight:bold;">N/A</span> + <div class="well well-sm" id="dpdresults">N/A</div> </div> - </div> - </div> - <!-- - <div class="panel panel-default"> - <div class="panel-heading">Calibration</div> - <div class="panel-body"> + <div>Calibration needs to be done once before the PA model can be trained. Every time calibration is changed, the predistortion parameters are invalidated!</div> - <button type="button" class="btn btn-sm btn-info" id="calibratebtn"> + <button type="button" class="btn btn-sm btn-warning" id="calibratebtn"> Calibrate</button> - <button type="button" class="btn btn-sm btn-info" id="calibraterefreshbtn"> - Refresh results</button> - <div>Calibration results:<span id="calibrationresults">N/A<span></div> </div> </div> + <!-- <div class="panel panel-default"> <div class="panel-heading">Capture TX and RX frames</div> <div class="panel-body"> |