mirror of
https://github.com/CopterExpress/clever-show.git
synced 2026-06-08 21:14:31 +00:00
Merge with master
This commit is contained in:
@@ -13,11 +13,10 @@ ModelStateRole = 999
|
||||
|
||||
|
||||
class CopterData:
|
||||
class_basic_attrs = indexed.IndexedOrderedDict([('copter_id', None), ('anim_id', None),
|
||||
('batt_v', None), ('batt_p', None),
|
||||
('sys_status', None), ('cal_status', None), ('selfcheck', None),
|
||||
('position', None), ("time_delta", None),
|
||||
("client", None), ])
|
||||
class_basic_attrs = indexed.IndexedOrderedDict([('copter_id', None), ('git_ver', None), ('anim_id', None),
|
||||
('battery', None), ('sys_status', None), ('cal_status', None),
|
||||
('mode', None), ('selfcheck', None), ('position', None),
|
||||
('start_pos', None), ('time_delta', None), ('client', None)])
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.attrs_dict = self.class_basic_attrs.copy()
|
||||
@@ -63,7 +62,7 @@ class StatedCopterData(CopterData):
|
||||
|
||||
class Checks:
|
||||
all_checks = {}
|
||||
takeoff_checklist = (2, 3, 4, 5, 6)
|
||||
takeoff_checklist = (3, 4, 6, 7, 8)
|
||||
|
||||
|
||||
class CopterDataModel(QtCore.QAbstractTableModel):
|
||||
@@ -75,8 +74,8 @@ class CopterDataModel(QtCore.QAbstractTableModel):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(CopterDataModel, self).__init__(parent)
|
||||
self.headers = ('copter ID', ' animation ID ', 'batt V', 'batt %', ' system ',
|
||||
'calibration', 'selfcheck', 'current x y z yaw frame_id', 'time delta')
|
||||
self.headers = ('copter ID', 'version', ' animation ID ', ' battery ', ' system ', 'calibration',
|
||||
' mode ', 'selfcheck', 'current x y z yaw frame_id', ' start x y z ', 'dt')
|
||||
self.data_contents = []
|
||||
|
||||
self.on_id_changed = None
|
||||
@@ -86,7 +85,6 @@ class CopterDataModel(QtCore.QAbstractTableModel):
|
||||
def insertRows(self, contents, position='last', parent=QtCore.QModelIndex()):
|
||||
rows = len(contents)
|
||||
position = len(self.data_contents) if position == 'last' else position
|
||||
|
||||
self.beginInsertRows(parent, position, position + rows - 1)
|
||||
self.data_contents[position:position] = contents
|
||||
|
||||
@@ -263,25 +261,25 @@ def col_check(col):
|
||||
|
||||
|
||||
@col_check(1)
|
||||
def check_ver(item):
|
||||
if not item:
|
||||
return None
|
||||
return True
|
||||
|
||||
@col_check(2)
|
||||
def check_anim(item):
|
||||
if not item:
|
||||
return None
|
||||
return str(item) != 'No animation'
|
||||
|
||||
|
||||
@col_check(2)
|
||||
def check_bat_v(item):
|
||||
if not item:
|
||||
return None
|
||||
return float(item) > 3.2
|
||||
|
||||
|
||||
@col_check(3)
|
||||
def check_bat_p(item):
|
||||
def check_bat(item):
|
||||
if not item:
|
||||
return None
|
||||
return float(item) > 30
|
||||
|
||||
if item == "NO_INFO":
|
||||
return False
|
||||
else:
|
||||
return float(item.split(' ')[1][:-1]) > 30
|
||||
|
||||
@col_check(4)
|
||||
def check_sys_status(item):
|
||||
@@ -289,30 +287,40 @@ def check_sys_status(item):
|
||||
return None
|
||||
return item == "STANDBY"
|
||||
|
||||
|
||||
@col_check(5)
|
||||
def check_cal_status(item):
|
||||
if not item:
|
||||
return None
|
||||
return item == "OK"
|
||||
|
||||
|
||||
@col_check(6)
|
||||
def check_mode(item):
|
||||
if not item:
|
||||
return None
|
||||
return (item != "NO_FCU") and not ("CMODE" in item)
|
||||
|
||||
|
||||
@col_check(7)
|
||||
def check_selfcheck(item):
|
||||
if not item:
|
||||
return None
|
||||
return item == "OK"
|
||||
|
||||
|
||||
@col_check(7)
|
||||
@col_check(8)
|
||||
def check_pos_status(item):
|
||||
if not item:
|
||||
return None
|
||||
return str(item).split(' ')[0] != 'nan'
|
||||
return item.split(' ')[0] != 'nan' and item.split(' ')[0] != 'NO_POS'
|
||||
|
||||
@col_check(9)
|
||||
def check_start_pos_status(item):
|
||||
if not item:
|
||||
return None
|
||||
return str(item).split(' ')[0] != 'NO_POS'
|
||||
|
||||
|
||||
|
||||
@col_check(8)
|
||||
@col_check(10)
|
||||
def check_time_delta(item):
|
||||
if not item:
|
||||
return None
|
||||
@@ -335,7 +343,7 @@ def takeoff_checks(copter_item):
|
||||
|
||||
def flip_checks(copter_item):
|
||||
for col in Checks.takeoff_checklist:
|
||||
if col != 4:
|
||||
if col != 4 or col != 7:
|
||||
if not Checks.all_checks[col](copter_item[col]):
|
||||
return False
|
||||
else:
|
||||
|
||||
@@ -13,7 +13,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.resize(1220, 761)
|
||||
MainWindow.resize(1360, 761)
|
||||
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||
self.centralwidget.setEnabled(True)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
@@ -35,9 +35,10 @@ class Ui_MainWindow(object):
|
||||
self.tableView.setWordWrap(True)
|
||||
self.tableView.setObjectName("tableView")
|
||||
self.tableView.horizontalHeader().setCascadingSectionResizes(False)
|
||||
self.tableView.horizontalHeader().setDefaultSectionSize(125)
|
||||
self.tableView.horizontalHeader().setDefaultSectionSize(50)
|
||||
self.tableView.horizontalHeader().setMinimumSectionSize(50)
|
||||
self.tableView.horizontalHeader().setStretchLastSection(True)
|
||||
self.tableView.verticalHeader().setVisible(False)
|
||||
self.horizontalLayout.addWidget(self.tableView)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
|
||||
@@ -186,7 +187,7 @@ class Ui_MainWindow(object):
|
||||
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1220, 26))
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1360, 25))
|
||||
self.menubar.setObjectName("menubar")
|
||||
self.menuOptions = QtWidgets.QMenu(self.menubar)
|
||||
self.menuOptions.setObjectName("menuOptions")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1220</width>
|
||||
<width>1360</width>
|
||||
<height>761</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -50,7 +50,7 @@
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>125</number>
|
||||
<number>50</number>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderMinimumSectionSize">
|
||||
<number>50</number>
|
||||
@@ -58,6 +58,9 @@
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -375,8 +378,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1220</width>
|
||||
<height>26</height>
|
||||
<width>1360</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuOptions">
|
||||
|
||||
@@ -169,51 +169,6 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.ui.takeoff_button.setEnabled(False)
|
||||
self.ui.flip_button.setEnabled(False)
|
||||
|
||||
@pyqtSlot()
|
||||
def selfcheck_selected_old(self):
|
||||
for copter_data_row in self.model.user_selected():
|
||||
client = copter_data_row.client
|
||||
|
||||
client.get_response("anim_id", self.set_copter_data, callback_args=(1, copter_data_row))
|
||||
client.get_response("batt_voltage", self.set_copter_data, callback_args=(2, copter_data_row))
|
||||
client.get_response("cell_voltage", self.set_copter_data, callback_args=(3, copter_data_row))
|
||||
client.get_response("sys_status", self.set_copter_data, callback_args=(4, copter_data_row))
|
||||
client.get_response("cal_status", self.set_copter_data, callback_args=(5, copter_data_row))
|
||||
client.get_response("selfcheck", self.set_copter_data, callback_args=(6, copter_data_row))
|
||||
client.get_response("position", self.set_copter_data, callback_args=(7, copter_data_row))
|
||||
client.get_response("time", self.set_copter_data, callback_args=(8, copter_data_row))
|
||||
|
||||
def set_copter_data(self, value, col, copter_data_row):
|
||||
row = self.model.get_row_index(copter_data_row)
|
||||
if row is None:
|
||||
logging.error("No such client!")
|
||||
return
|
||||
|
||||
if col == 1:
|
||||
data = value
|
||||
elif col == 2:
|
||||
data = "{}".format(round(float(value), 3))
|
||||
elif col == 3:
|
||||
batt_percent = ((float(value) - 3.2) / (4.2 - 3.2)) * 100 # TODO config
|
||||
data = "{}".format(round(batt_percent, 3))
|
||||
elif col == 4:
|
||||
data = str(value)
|
||||
elif col == 5:
|
||||
data = str(value)
|
||||
elif col == 6:
|
||||
data = value
|
||||
elif col == 7:
|
||||
data = str(value)
|
||||
elif col == 8:
|
||||
data = "{}".format(round(float(value) - time.time(), 3))
|
||||
if abs(float(data)) > 1:
|
||||
copter_data_row.client.send_message("repair_chrony")
|
||||
else:
|
||||
logging.error("No column matched for response")
|
||||
return
|
||||
|
||||
self.signals.update_data_signal.emit(row, col, data, ModelDataRole)
|
||||
|
||||
@pyqtSlot()
|
||||
def selfcheck_selected(self):
|
||||
for copter_data_row in self.model.user_selected():
|
||||
@@ -223,13 +178,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
@pyqtSlot(str)
|
||||
def update_table_data(self, message):
|
||||
fields = message.split('`')
|
||||
logging.info(fields[8])
|
||||
# copter_id git_version animation_id battery_v battery_p system_status calibration_status mode selfcheck current_position start_position copter_time
|
||||
copter_id = fields[0]
|
||||
git_version = fields[1]
|
||||
animation_id = fields[2]
|
||||
battery_v = fields[3]
|
||||
battery_p = fields[4]
|
||||
if battery_v == 'nan' or battery_p == 'nan':
|
||||
battery_info = "NO_INFO"
|
||||
else:
|
||||
battery_info = "{}V {}%".format(battery_v, battery_p)
|
||||
sys_status = fields[5]
|
||||
cal_status = fields[6]
|
||||
mode = fields[7]
|
||||
@@ -237,28 +195,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
current_pos = fields[9]
|
||||
start_pos = fields[10]
|
||||
copter_time = fields[11]
|
||||
time_delta = "{}".format(round(float(copter_time) - time.time(), 3))
|
||||
row = self.model.get_row_index(self.model.get_row_by_attr('copter_id', copter_id))
|
||||
logging.info("Row = {}".format(row))
|
||||
self.signals.update_data_signal.emit(row, 1, animation_id, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 2, battery_v, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 3, battery_p, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 1, git_version, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 2, animation_id, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 3, battery_info, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 4, sys_status, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 5, cal_status, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 6, selfcheck, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 7, current_pos, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 8, "{}".format(round(float(copter_time) - time.time(), 3)), ModelDataRole)
|
||||
|
||||
#def set_copter_id(self, value, copter_data_row):
|
||||
# col = 0
|
||||
# row = self.model.get_row_index(copter_data_row)
|
||||
# if row is None:
|
||||
# logging.error("No such client!")
|
||||
# return
|
||||
# logging.info("SET COPTER ID TO {}".format(value))
|
||||
#
|
||||
# copter_data_row.client.copter_id = value
|
||||
# self.signals.update_data_signal.emit(row, col, value, ModelDataRole)
|
||||
# self.signals.update_data_signal.emit(row, col, True, ModelStateRole)
|
||||
self.signals.update_data_signal.emit(row, 6, mode, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 7, selfcheck, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 8, current_pos, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 9, start_pos, ModelDataRole)
|
||||
self.signals.update_data_signal.emit(row, 10, time_delta, ModelDataRole)
|
||||
|
||||
@pyqtSlot(QtCore.QModelIndex)
|
||||
def selfcheck_info_dialog(self, index):
|
||||
@@ -408,13 +356,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
print("Selected directory:", path)
|
||||
files = [file for file in glob.glob(path + '/*.csv')]
|
||||
names = [os.path.basename(file).split(".")[0] for file in files]
|
||||
# print(files)
|
||||
for file, name in zip(files, names):
|
||||
for copter in self.model.user_selected():
|
||||
if name == copter.copter_id:
|
||||
copter.client.send_file(file, "animation.csv") # TODO config
|
||||
else:
|
||||
print("Filename has no matches with any drone selected")
|
||||
logging.info("Filename has no matches with any drone selected")
|
||||
|
||||
@pyqtSlot()
|
||||
def send_calibrations(self):
|
||||
@@ -430,7 +377,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
if name == copter.copter_id:
|
||||
copter.client.send_file(file, "/home/pi/catkin_ws/src/clever/clever/camera_info/calibration.yaml")
|
||||
else:
|
||||
print("Filename has no matches with any drone selected")
|
||||
logging.info("Filename has no matches with any drone selected")
|
||||
|
||||
@pyqtSlot()
|
||||
def send_configurations(self):
|
||||
@@ -443,7 +390,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
for section in sendable_config.sections():
|
||||
for option in dict(sendable_config.items(section)):
|
||||
value = sendable_config[section][option]
|
||||
logging.debug("Got item from config:".format(section, option, value))
|
||||
logging.debug("Got item from config: {} {} {}".format(section, option, value))
|
||||
options.append(ConfigOption(section, option, value))
|
||||
|
||||
for copter in self.model.user_selected():
|
||||
|
||||
Reference in New Issue
Block a user