aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/dpd/Measure.py7
-rw-r--r--python/dpd/RX_Agc.py5
-rwxr-xr-xpython/dpdce.py38
-rwxr-xr-xpython/gui/api.py3
-rw-r--r--python/gui/static/js/odr-predistortion.js30
-rw-r--r--python/gui/static/js/odr.js48
-rw-r--r--python/gui/templates/predistortion.html19
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">