Skip to content
Commits on Source (2)
# server.py # server.py
from flask import Flask, render_template from flask import Flask, render_template
from flask_socketio import SocketIO from flask_socketio import SocketIO
from flask_cors import CORS import numpy as np
import json
app = Flask(__name__) app = Flask(__name__)
CORS(app)
socketio = SocketIO(app, socketio = SocketIO(app,
async_mode='threading', async_mode='threading',
) )
# Function to generate a random NumPy matrix
def generate_matrix():
return np.random.rand(3, 3)
# Function to send the matrix to the client
def send_matrix():
matrix = generate_matrix()
matrix_json = json.dumps(matrix.tolist())
socketio.emit('matrix', matrix_json)
# Background thread to send the matrix every 5 seconds
def background_thread():
while True:
send_matrix()
socketio.sleep(5)
# Route for the HTML page # Route for the HTML page
@app.route('/') @app.route('/')
def index(): def index():
...@@ -30,4 +47,7 @@ def handle_message(message): ...@@ -30,4 +47,7 @@ def handle_message(message):
print('Received message:', message) print('Received message:', message)
if __name__ == '__main__': if __name__ == '__main__':
socketio.run(app, host="sharknirws.shark-nir.lbto.org", port=5001)
socketio.start_background_task(target=background_thread)
socketio.run(app, host="0.0.0.0", port=5002)
...@@ -5,31 +5,40 @@ ...@@ -5,31 +5,40 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask-SocketIO Example</title> <title>Flask-SocketIO Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.4.0/socket.io.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.4.0/socket.io.js"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> -->
<script> <script>
// Connect to Socket.IO server // Connect to Socket.IO server
// var socket = io.connect('http://' + document.domain + ':' + location.port);
const socket = io.connect({ const socket = io.connect({
// transports: ['websocket'], // transports: ['websocket'],
}); });
// Event handlers // Event handlers
socket.on('connect', () => { socket.on('connect', () => {
console.log('Connected'); console.log('Connected');
}); });
socket.on('disconnect', () => { socket.on('disconnect', () => {
console.log('Disconnected'); console.log('Disconnected');
}); });
socket.on('message', (data) => { socket.on('message', (data) => {
console.log('Received message:', data); console.log('Received message:', data);
}); });
// Example: Sending a message
function sendMessage() { socket.on('matrix', function(matrix_json) {
const message = document.getElementById('message').value; var matrix = JSON.parse(matrix_json);
socket.emit('message', message); console.log('Received matrix:');
} console.log(matrix);
});
// // Example: Sending a message
// function sendMessage() {
// const message = document.getElementById('message').value;
// socket.emit('message', message);
// }
</script> </script>
</head> </head>
<body> <body>
......
...@@ -14,15 +14,24 @@ from util import variables as uvars ...@@ -14,15 +14,24 @@ from util import variables as uvars
from util.master_listener_davide import thread from util.master_listener_davide import thread
from util.mini_os import obsController from util.mini_os import obsController
signs_list = [] ### Focus only on the 8x8 pixel matrix centered on the centroid
with open(str(uvars.sign_map), "r") as f: def focus_on_centroid(a, cx, cy, s=4):
for line in f: # a is an array-like matrix , s is an Int
for x in line.split(): cx = int(cx)*32 + 32 # cx and cy are normalized in [-1,1] -> now are renormalized in [0,64]
signs_list.append(int(x)) cy = int(cy)*32 + 32
signs = np.array(signs_list)
if(s>cx or s>cy):
s = min(cx,cy)
if(s>len(a)-cx or s>len(a)-cy):
s = min(s , len(a)-cx , len(a)-cy)
a_focused = a[cx-s : cx+s , cy-s : cy+s]
return a_focused
class RtcObject(object): class RtcObject(object):
def __init__(self): def __init__(self):
self.counter = 0 self.counter = 0
self.todos = [] self.todos = []
...@@ -33,11 +42,13 @@ class RtcObject(object): ...@@ -33,11 +42,13 @@ class RtcObject(object):
self.thread = thread self.thread = thread
self.obsController = obsController self.obsController = obsController
def reset(self): def reset(self):
print("reset") print("reset")
status = self.obsController.RTCTTResetBCU() status = self.obsController.RTCTTResetBCU()
return status return status
def resurrect(self): def resurrect(self):
print("import") print("import")
from SHINS_SW_TEST.SHINS_TEST_DEBUG import SHINS_TEST_DEBUG from SHINS_SW_TEST.SHINS_TEST_DEBUG import SHINS_TEST_DEBUG
...@@ -50,6 +61,7 @@ class RtcObject(object): ...@@ -50,6 +61,7 @@ class RtcObject(object):
print(status) print(status)
return status return status
def resurrect2(self): def resurrect2(self):
print('resurrect2') print('resurrect2')
rtc_s = uvars.rtc_s_base.copy() rtc_s = uvars.rtc_s_base.copy()
...@@ -75,6 +87,7 @@ class RtcObject(object): ...@@ -75,6 +87,7 @@ class RtcObject(object):
print("Exit status: {}".format(status)) print("Exit status: {}".format(status))
ufun.error_handler(status, "RTCTTStart") ufun.error_handler(status, "RTCTTStart")
def uploadRTC(self, modal=True): def uploadRTC(self, modal=True):
rtc_s = uvars.rtc_s_base.copy() rtc_s = uvars.rtc_s_base.copy()
if modal: if modal:
...@@ -110,8 +123,7 @@ class RtcObject(object): ...@@ -110,8 +123,7 @@ class RtcObject(object):
mode = "Modal" if modal else "Zonal" mode = "Modal" if modal else "Zonal"
print("Enabling {} Mode... DONE".format(mode)) print("Enabling {} Mode... DONE".format(mode))
def zonalCommand(self, data): def zonalCommand(self, data):
print("chiamata effettuata") print("chiamata effettuata")
normalize_strain = 1#6.666667 normalize_strain = 1#6.666667
...@@ -133,7 +145,8 @@ class RtcObject(object): ...@@ -133,7 +145,8 @@ class RtcObject(object):
print(e) print(e)
status = 1 status = 1
return status return status
def move_soul(self, data, apply_movement=False): def move_soul(self, data, apply_movement=False):
self.soul_deltas = data self.soul_deltas = data
print("Received data: {}".format(data)) print("Received data: {}".format(data))
...@@ -215,51 +228,61 @@ class RtcObject(object): ...@@ -215,51 +228,61 @@ class RtcObject(object):
print("Something went wrong, no action received") print("Something went wrong, no action received")
print("Reached end of command") print("Reached end of command")
return status return status
def read(self, id): def read(self, id):
for todo in self.todos: for todo in self.todos:
if todo["id"] == id: if todo["id"] == id:
return todo return todo
def create(self, data): def create(self, data):
todo = data todo = data
self.todos.append(todo) self.todos.append(todo)
return todo return todo
def update(self, id, data): def update(self, id, data):
todo = self.read(id) todo = self.read(id)
todo.update(data) todo.update(data)
return todo return todo
def delete(self, id): def delete(self, id):
todo = self.read(id) todo = self.read(id)
self.todos.remove(todo) self.todos.remove(todo)
@property @property
def centroid(self): def centroid(self):
status, [cx, cy] = self.obsController.getInternalSeqFloatVariable("RtcCentroidOrigin") status, [cx, cy] = self.obsController.getInternalSeqFloatVariable("RtcCentroidOrigin")
return [cx, cy] return [cx, cy]
@centroid.setter @centroid.setter
def centroid(self, cx_cy): def centroid(self, cx_cy):
cx, cy = cx_cy cx, cy = cx_cy
status = self.obsController.RTCTTSetCentroidPos(cx, cy) status = self.obsController.RTCTTSetCentroidPos(cx, cy)
return status return status
def flatten(self): def flatten(self):
modes = [0] * 96#39 modes = [0] * 96#39
status = self.obsController.RTCTTModeUpload(modes, absolute=True) status = self.obsController.RTCTTModeUpload(modes, absolute=True)
status = self.load_ncpa(name="zeri.txt") status = self.load_ncpa(name="zeri.txt")
return status return status
def close_loop(self): def close_loop(self):
status = self.obsController.RTCTTCloseLoop() status = self.obsController.RTCTTCloseLoop()
return status return status
def open_loop(self): def open_loop(self):
status = self.obsController.RTCTTOpenLoop() status = self.obsController.RTCTTOpenLoop()
return status return status
def frequency(self, freq): def frequency(self, freq):
"""Set the loop frequency""" """Set the loop frequency"""
...@@ -267,7 +290,8 @@ class RtcObject(object): ...@@ -267,7 +290,8 @@ class RtcObject(object):
status = self.obsController.RTCTTExecuteSetup(rtc_s) status = self.obsController.RTCTTExecuteSetup(rtc_s)
return status return status
def tint(self, t): def tint(self, t):
"""Set integration time""" """Set integration time"""
...@@ -277,6 +301,7 @@ class RtcObject(object): ...@@ -277,6 +301,7 @@ class RtcObject(object):
status = self.obsController.RTCTTExecuteSetup(rtc_s) status = self.obsController.RTCTTExecuteSetup(rtc_s)
return status return status
def patrol(self, b): def patrol(self, b):
"""Set params to enable or disable patrol camera mode""" """Set params to enable or disable patrol camera mode"""
...@@ -288,7 +313,7 @@ class RtcObject(object): ...@@ -288,7 +313,7 @@ class RtcObject(object):
"TTWINCOORDY": "0", "TTWINCOORDY": "0",
"TTWINCOLS": "640", "TTWINCOLS": "640",
"TTWINROWS": "512", "TTWINROWS": "512",
"TTFRAMERATE": "200", #200 "TTFRAMERATE": "200",
"TTNSLOPEPIXELS": "16", "TTNSLOPEPIXELS": "16",
"TTBIASFILE": "", "TTBIASFILE": "",
"TTPIXELGAINFILE": "", "TTPIXELGAINFILE": "",
...@@ -344,6 +369,7 @@ class RtcObject(object): ...@@ -344,6 +369,7 @@ class RtcObject(object):
return status return status
def threshold(self, t): def threshold(self, t):
"""Set the RTC Threshold""" """Set the RTC Threshold"""
...@@ -351,6 +377,7 @@ class RtcObject(object): ...@@ -351,6 +377,7 @@ class RtcObject(object):
return status return status
def get_threshold(self): def get_threshold(self):
"""Get the RTC Threshold""" """Get the RTC Threshold"""
...@@ -368,6 +395,7 @@ class RtcObject(object): ...@@ -368,6 +395,7 @@ class RtcObject(object):
return [ str(dark.name).decode('utf-8') for dark in sorted(uvars.dark_path.glob("*.dat")) ] return [ str(dark.name).decode('utf-8') for dark in sorted(uvars.dark_path.glob("*.dat")) ]
def new_dark(self): def new_dark(self):
"""Create a new dark""" """Create a new dark"""
...@@ -385,6 +413,7 @@ class RtcObject(object): ...@@ -385,6 +413,7 @@ class RtcObject(object):
return filename return filename
def load_dark(self, name): def load_dark(self, name):
"""Load a dark file""" """Load a dark file"""
rtc_s = {"TTBIASFILE": name} rtc_s = {"TTBIASFILE": name}
...@@ -392,6 +421,7 @@ class RtcObject(object): ...@@ -392,6 +421,7 @@ class RtcObject(object):
return status return status
def get_current_dark(self): def get_current_dark(self):
pass pass
...@@ -404,6 +434,7 @@ class RtcObject(object): ...@@ -404,6 +434,7 @@ class RtcObject(object):
return [ str(gain.name).decode('utf-8') for gain in sorted(uvars.gain_path.glob("*.dat")) ] return [ str(gain.name).decode('utf-8') for gain in sorted(uvars.gain_path.glob("*.dat")) ]
def new_gain(self, gain_type, centroid_size): def new_gain(self, gain_type, centroid_size):
"""Create a new gain""" """Create a new gain"""
rtc_s = { rtc_s = {
...@@ -413,6 +444,7 @@ class RtcObject(object): ...@@ -413,6 +444,7 @@ class RtcObject(object):
status = self.obsController.RTCTTExecuteSetup(rtc_s) status = self.obsController.RTCTTExecuteSetup(rtc_s)
return status return status
def load_gain(self, name): def load_gain(self, name):
"""Load a gain file""" """Load a gain file"""
rtc_s = { rtc_s = {
...@@ -437,27 +469,28 @@ class RtcObject(object): ...@@ -437,27 +469,28 @@ class RtcObject(object):
status = self.obsController.RTCTTExecuteSetup(rtc_s) status = self.obsController.RTCTTExecuteSetup(rtc_s)
return status return status
def tiptilt(self, modes=[0,0,0,0], absolute=False): def tiptilt(self, modes=[0,0,0,0], absolute=False):
print("Loaded Modes {}".format(modes)) print("Loaded Modes {}".format(modes))
status = self.obsController.RTCTTModeUpload(modes=modes, absolute=absolute) status = self.obsController.RTCTTModeUpload(modes=modes, absolute=absolute)
return status return status
def teccam_http_start(self):
status, _ = self.obsController.RTCTTSendCameraCommand("exec httpserver start")
return status
def teccam_custom_command(self, command): def teccam_custom_command(self, command):
status, res = self.obsController.RTCTTSendCameraCommand(command) status, res = self.obsController.RTCTTSendCameraCommand(command)
return res return res
def save(self): def save(self):
data = self.data() data = self.data()
now = Time.now().isot now = Time.now().isot
filename = "/data/rtc/rtc-panel-save-{}.json".format(now) filename = "/data/rtc/rtc-panel-save-{}.json".format(now)
with open(filename, 'w') as f: with open(filename, 'w') as f:
json.dump(data, f) json.dump(data, f)
return filename return filename
def save_flat(self): def save_flat(self):
"""Save the current flat in a file""" """Save the current flat in a file"""
...@@ -468,12 +501,14 @@ class RtcObject(object): ...@@ -468,12 +501,14 @@ class RtcObject(object):
print(flat_name) print(flat_name)
return flat_name return flat_name
def cloud_samples(self, s): def cloud_samples(self, s):
print("prima : samples = {}".format(self.thread.cloud_samples)) print("prima : samples = {}".format(self.thread.cloud_samples))
status = self.thread.cloud_samples = s status = self.thread.cloud_samples = s
print("dopo : samples = {}".format(self.thread.cloud_samples)) print("dopo : samples = {}".format(self.thread.cloud_samples))
return status return status
def get_cloud_samples(self): def get_cloud_samples(self):
return self.thread.cloud_samples return self.thread.cloud_samples
...@@ -485,6 +520,7 @@ class RtcObject(object): ...@@ -485,6 +520,7 @@ class RtcObject(object):
"""List ncpa files""" """List ncpa files"""
return [ str(ncpa.name).decode('utf-8') for ncpa in sorted(uvars.ncpa_path.glob("*.txt")) ] return [ str(ncpa.name).decode('utf-8') for ncpa in sorted(uvars.ncpa_path.glob("*.txt")) ]
def load_ncpa(self, name): def load_ncpa(self, name):
"""Load a ncpa file""" """Load a ncpa file"""
# load saved file # load saved file
...@@ -520,11 +556,18 @@ class RtcObject(object): ...@@ -520,11 +556,18 @@ class RtcObject(object):
print("Finished") print("Finished")
return status return status
def save_ncpa(self): def save_ncpa(self):
"""Save the current ncpa in a file""" """Save the current ncpa in a file"""
ncpa_name = ufun.save_ncpa(os=self.obsController) ncpa_name = ufun.save_ncpa(os=self.obsController)
print(ncpa_name) print(ncpa_name)
return ncpa_name return ncpa_name
def getNCPARotationStatus(self):
print("Status ncpa rotation in arrivo... status is {}".format(self.rotating_ncpa))
return self.rotating_ncpa
def rotateNCPA(self, action): def rotateNCPA(self, action):
...@@ -569,9 +612,9 @@ class RtcObject(object): ...@@ -569,9 +612,9 @@ class RtcObject(object):
time.sleep(sleep) time.sleep(sleep)
return 1 return 1
def getNCPARotationStatus(self): ##############
print("Status ncpa rotation in arrivo... status is {}".format(self.rotating_ncpa)) # Plot stuff #
return self.rotating_ncpa ##############
@property @property
...@@ -666,7 +709,14 @@ class RtcObject(object): ...@@ -666,7 +709,14 @@ class RtcObject(object):
return gain return gain
def data_dm(self, imshape): def data_dm(self):
signs_list = []
with open(str(uvars.sign_map), "r") as f:
for line in f:
for x in line.split():
signs_list.append(int(x))
signs = np.array(signs_list)
# Diagnostics # Diagnostics
shape = self.thread.shape shape = self.thread.shape
...@@ -680,12 +730,11 @@ class RtcObject(object): ...@@ -680,12 +730,11 @@ class RtcObject(object):
"actuators": uvars.actuators.tolist(), "actuators": uvars.actuators.tolist(),
"shape": (shape*signs).tolist(), "shape": (shape*signs).tolist(),
"flat": (np.array(dmflat[0:97])).tolist(), "flat": (np.array(dmflat[0:97])).tolist(),
#"dm_shape_no_flat" : dm_shape_no_flat,
"min": round(shape.min(),2), "min": round(shape.min(),2),
"max": round(shape.max(),2), "max": round(shape.max(),2),
"min_no_flat" : round(min(dm_shape_no_flat),2), "min_no_flat" : round(min(dm_shape_no_flat),2),
"max_no_flat" : round(max(dm_shape_no_flat),2), "max_no_flat" : round(max(dm_shape_no_flat),2),
"image_shape": list(imshape), # "image_shape": list(imshape),
"skp_cmd" : self.thread.tt_cmd[1] "skp_cmd" : self.thread.tt_cmd[1]
} }
...@@ -699,9 +748,11 @@ class RtcObject(object): ...@@ -699,9 +748,11 @@ class RtcObject(object):
def data_cloud(self, imshape, centroid): def data_cloud(self, imshape, centroid):
# Diagnostics
centroids_x = self.thread.centroid_x centroids_x = self.thread.centroid_x
centroids_y = self.thread.centroid_y centroids_y = self.thread.centroid_y
cloud = np.flip(self.thread.centroid_matrix.T, 1) cloud = np.flip(self.thread.centroid_matrix.T, 1)
cx,cy = centroid cx,cy = centroid
rmsX = np.std(centroids_x)*21 # px 2 mas, plate scale = 21 mas/px rmsX = np.std(centroids_x)*21 # px 2 mas, plate scale = 21 mas/px
rmsY = np.std(centroids_y)*21 # px 2 mas rmsY = np.std(centroids_y)*21 # px 2 mas
...@@ -732,29 +783,18 @@ class RtcObject(object): ...@@ -732,29 +783,18 @@ class RtcObject(object):
return cld return cld
def data(self): def data(self):
# Diagnostics
image = self.rtc_image image = self.rtc_image
imshape = image.shape imshape = image.shape
# OS
centroid = self.centroid centroid = self.centroid
data_cloud = self.data_cloud(imshape, centroid) data_cloud = self.data_cloud(imshape, centroid)
data_cred = self.data_cred(image, centroid) data_cred = self.data_cred(image, centroid)
### Focus only on the 8x8 pixel matrix centered on the centroid
def focus_on_centroid(a, cx, cy, s=4):
# a is an array-like matrix , s is an Int
cx = int(cx)*32 + 32 # cx and cy are normalized in [-1,1] -> now are renormalized in [0,64]
cy = int(cy)*32 + 32
if(s>cx or s>cy):
s = min(cx,cy)
if(s>len(a)-cx or s>len(a)-cy):
s = min(s , len(a)-cx , len(a)-cy)
a_focused = a[cx-s : cx+s , cy-s : cy+s]
return a_focused
cropped_cred = focus_on_centroid( np.array(data_cred["data"]) , data_cloud["cx"] ,data_cloud["cy"], s=4) cropped_cred = focus_on_centroid( np.array(data_cred["data"]) , data_cloud["cx"] ,data_cloud["cy"], s=4)
...@@ -772,7 +812,7 @@ class RtcObject(object): ...@@ -772,7 +812,7 @@ class RtcObject(object):
response = { response = {
"cred": data_cred, "cred": data_cred,
"gain": self.data_gain(imshape), "gain": self.data_gain(imshape),
"dm": self.data_dm(imshape), "dm": self.data_dm(), # removed imshape as parameter
"cloud": data_cloud, "cloud": data_cloud,
"cx": centroid[0], "cx": centroid[0],
"cy": centroid[1], "cy": centroid[1],
......
...@@ -18,17 +18,18 @@ ...@@ -18,17 +18,18 @@
$("#image-tot_flux-"+id).text(totFlux) $("#image-tot_flux-"+id).text(totFlux)
} }
if($("#image-wx-"+id)){ // cloud if (image.image_shape) {
$("#image-wx-"+id).text(image.wx / 2 * image.image_shape[0] ) if($("#image-wx-"+id)){ // cloud
$("#image-wy-"+id).text(image.wy / 2 * image.image_shape[1] ) $("#image-wx-"+id).text(image.wx / 2 * image.image_shape[0] )
$("#image-wy-"+id).text(image.wy / 2 * image.image_shape[1] )
$("#image-RMS_X-"+id).text(image.RMS_X / 2 * image.image_shape[0] )
$("#image-RMS_Y-"+id).text(image.RMS_Y / 2 * image.image_shape[1] ) $("#image-RMS_X-"+id).text(image.RMS_X / 2 * image.image_shape[0] )
// $("#image-cloud_samples"+id).text(image.RMS_X / 2 * image.image_shape[0] ) $("#image-RMS_Y-"+id).text(image.RMS_Y / 2 * image.image_shape[1] )
//console.log("AAAAA "+id) // $("#image-cloud_samples"+id).text(image.RMS_X / 2 * image.image_shape[0] )
//console.log(image.samples) //console.log("AAAAA "+id)
//console.log(image.samples)
}
} }
return [min, max] return [min, max]
......