-
-
Notifications
You must be signed in to change notification settings - Fork 33
/
vesc_ui.py
144 lines (121 loc) · 5.77 KB
/
vesc_ui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from PyQt6.QtWidgets import QMainWindow
from PyQt6.QtWidgets import QDialog
from PyQt6.QtWidgets import QWidget
from PyQt6.QtWidgets import QMessageBox,QVBoxLayout,QCheckBox,QButtonGroup
from PyQt6 import uic
from helper import res_path,classlistToIds
from PyQt6.QtCore import QTimer
import main
from base_ui import WidgetUI
import math
from base_ui import CommunicationHandler
import portconf_ui
class VescUI(WidgetUI,CommunicationHandler):
prefix = None
def __init__(self, main=None, unique=None):
WidgetUI.__init__(self, main,'vesc.ui')
CommunicationHandler.__init__(self)
self.main = main #type: main.MainUi
self.timer = QTimer(self)
self.pushButton_apply.clicked.connect(self.apply)
self.pushButton_manualRead.clicked.connect(self.manualEncPosRead)
self.pushButton_eraseOffset.clicked.connect(self.eraseOffset)
self.pushButton_refresh.clicked.connect(self.init_ui)
self.timer.timeout.connect(self.updateTimer)
self.prefix = unique
self.canOptions = portconf_ui.CanOptionsDialog(0,"CAN",main)
self.pushButton_cansettings.clicked.connect(self.canOptions.exec)
#self.checkBox_useEncoder.stateChanged.connect(lambda val : self.sendValue("vesc","useencoder",(0 if val == 0 else 1),instance=self.prefix))
self.register_callback("vesc","offbcanid",self.spinBox_OFFB_can_id.setValue,self.prefix,int)
self.register_callback("vesc","vesccanid",self.spinBox_VESC_can_Id.setValue,self.prefix,int)
self.register_callback("vesc","useencoder",self.updateEncoderUI,self.prefix,int)
self.register_callback("vesc","offset",self.updateOffset,self.prefix,int)
self.register_callback("vesc","errorflags",self.errorCb,self.prefix,int)
self.register_callback("vesc","encrate",self.label_encoder_rate.setText,self.prefix,str)
self.register_callback("vesc","voltage",lambda mv : self.label_voltage.setText(f"{mv/1000}V"),self.prefix,int)
self.register_callback("vesc","pos",self.posCb,self.prefix,int)
self.register_callback("vesc","vescstate",self.stateCb,self.prefix,int)
self.register_callback("vesc","torque",self.torqueCb,self.prefix,int)
self.init_ui()
def vescstate(self,i):
_result = "Invalid state"
if i == 0 :
_result = "No connection"
elif i == 1 :
_result = "vesc FW incompatible"
elif i == 2 :
_result = "Comm ok"
elif i == 3 :
_result = "vesc compatible"
elif i == 4 :
_result = "ready"
elif i == 5 :
_result = "error"
return _result
# Tab is currently shown
def showEvent(self,event):
self.init_ui()
self.timer.start(500)
# Tab is hidden
def hideEvent(self,event):
self.timer.stop()
def updateEncoderUI(self, dat):
self.checkBox_useEncoder.setChecked(dat)
visible = dat==1
self.label_6.setVisible(visible)
self.label_encoder_rate.setVisible(visible)
self.label_pos.setVisible(visible)
self.label_7.setVisible(visible)
self.horizontalSlider_pos.setVisible(visible)
self.line.setVisible(visible)
self.label_9.setVisible(visible)
self.doubleSpinBox_encoderOffset.setVisible(visible)
self.pushButton_eraseOffset.setVisible(visible)
def init_ui(self):
self.send_commands("vesc",["offbcanid", "vesccanid", "useencoder", "offset"],self.prefix)
def updateOffset(self, preset):
self.doubleSpinBox_encoderOffset.setValue(preset / 10000)
# def updateCanSpd(self,preset):
# self.comboBox_baud.setCurrentIndex(preset-3) # 3 is lowest preset!
def stateCb(self,state):
self.label_state.setText(self.vescstate(state))
if (state == 0) and (self.label_errors.isEnabled()):
self.label_errors.setEnabled(0)
self.label_voltage.setEnabled(0)
self.label_encoder_rate.setEnabled(0)
elif (state != 0) and (not self.label_errors.isEnabled()):
self.label_errors.setEnabled(1)
self.label_voltage.setEnabled(1)
self.label_encoder_rate.setEnabled(1)
def torqueCb(self,v):
vesc_torque = math.ceil(v / 100)
self.label_torque.setText(str(vesc_torque)) # not divide by 10000 but by 100 to display it in %
if vesc_torque >= 0:
self.progressBar_torqueneg.setValue(0)
self.progressBar_torquepos.setValue(vesc_torque)
else:
self.progressBar_torqueneg.setValue(-vesc_torque)
self.progressBar_torquepos.setValue(0)
def posCb(self,v):
vesc_encoder_position = ( 360 * v ) / 1000000000
self.label_pos.setText("{:.2f}".format(vesc_encoder_position))
self.horizontalSlider_pos.setValue(int(round(vesc_encoder_position)))
def errorCb(self,dat):
txt = "Ok"
if dat != 0:
txt = "Error code " + str(dat)
self.label_errors.setText(txt)
def updateTimer(self):
self.send_commands("vesc",["vescstate","errorflags","voltage","pos","encrate","torque"],self.prefix)
def apply(self):
OpenFFBoardCANId = str(self.spinBox_OFFB_can_id.value())
VESCCANId = str(self.spinBox_VESC_can_Id.value())
self.send_value("vesc","offbcanid",OpenFFBoardCANId,instance=self.prefix)
self.send_value("vesc","vesccanid",VESCCANId,instance=self.prefix)
self.send_value("vesc","useencoder",(1 if self.checkBox_useEncoder.isChecked() else 0),instance=self.prefix)
self.init_ui() # Update UI
def manualEncPosRead(self):
self.send_command("vesc","forceposread",instance=self.prefix)
def eraseOffset(self):
self.send_value("vesc","offset",0,instance=self.prefix)
self.init_ui()