add configurable dead zones for the pedals

add configurable combining of gas and clutch pedals
This commit is contained in:
n-e-y-s 2020-09-02 21:33:41 +02:00
parent 56ccc2137c
commit 9c041be630
2 changed files with 183 additions and 64 deletions

View File

@ -81,10 +81,19 @@
#define CALIB_DATA_MAGIC_NUMBER 0x27CA11B1 // change this when the struct definition changes
#define FLAG_INVERT_BRAKE 0x1 // invert brake pedal
#define FLAG_INVERT_GAS 0x2 // invert gas pedal
#define FLAG_INVERT_CLUTCH 0x4 // invert clutch pedal
#define FLAG_REVERSE_RIGHT_RED 0x8 // use right red button for reverse gear instead of the reverse sensor
#define FLAG1_INVERT_BRAKE 0x1 // invert brake pedal
#define FLAG1_INVERT_GAS 0x2 // invert gas pedal
#define FLAG1_INVERT_CLUTCH 0x4 // invert clutch pedal
#define FLAG1_REVERSE_RIGHT_RED 0x8 // use right red button for reverse gear instead of the reverse sensor
#define FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z 0x10 // combine clutch and gas
#define FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X 0x20 // combine clutch and gas
#define FLAG2_ENABLE_PEDALS 0x1
#define FLAG2_BRAKE_DEAD_ZONE (0x2|0x4|0x8) // deadZone_percent = ((flag & FLAG2_BRAKE_DEAD_ZONE) >> 1)*2
#define FLAG2_GAS_DEAD_ZONE (0x10|0x20|0x40) // deadZone_percent = ((flag & FLAG2_GAS_DEAD_ZONE) >> 4)*2
#define FLAG3_ENABLE_SHIFTER 0x1
#define FLAG3_CLUTCH_DEAD_ZONE (0x10|0x20|0x40) // deadZone_percent = ((flag & FLAG3_CLUTCH_DEAD_ZONE) >> 4)*2
typedef struct CalibData
{
@ -92,12 +101,12 @@ typedef struct CalibData
uint32_t calibID;
/* bool whether to automatically calibrate the pedals at a power cycle or use a static calibration */
uint8_t pedals_auto_calib;
/* flags, see the FLAG_* defines for the meaning of the bits */
uint8_t flags;
/* bool whether to use the pedals */
uint8_t use_pedals;
/* bool whether to use the shifter */
uint8_t use_shifter;
/* flag1, see the FLAG1_* defines for the meaning of the bits */
uint8_t flag1;
/* flag2, see the FLAG2_* defines for the meaning of the bits */
uint8_t flag2;
/* flag3, see the FLAG3_* defines for the meaning of the bits */
uint8_t flag3;
/* size of median filter to filter pedal values */
uint8_t pedal_median_size;
/* size of median filter to filter shifter values */
@ -129,7 +138,7 @@ static Calibration calibDefault = {
{
CALIB_DATA_MAGIC_NUMBER,
1, /* pedals auto calib */
0, /* flags, everything on default */
0, /* flag1, everything on default */
1, /* use pedals */
1, /* use shifter */
0, /* pedals median size */
@ -195,14 +204,18 @@ static Pedal* gasPedal = 0;
static Pedal* brakePedal = 0;
static Pedal* clutchPedal = 0;
int axisValue(struct Pedal* input) {
int axisValue(struct Pedal* input, int dead_zone)
{
int physicalRange = input->max - input->min;
int delta = dead_zone == 0 ? 0 : ((int32_t)physicalRange*(int32_t)dead_zone/(int32_t)100);
int max = input->max - delta;
int min = input->min + delta;
physicalRange = max - min;
if (physicalRange == 0) {
return 0;
}
int result = map(input->cur, input->min, input->max, 0, MAX_AXIS);
int result = map(input->cur, min, max, 0, MAX_AXIS);
if (result < 0) {
return 0;
@ -213,7 +226,7 @@ int axisValue(struct Pedal* input) {
return result;
}
void processPedal(struct Pedal* input, SignalFilter *flt, uint8_t filterSize)
void processPedal(struct Pedal* input, SignalFilter *flt, uint8_t filterSize, int dead_zone)
{
input->cur = apply_filter(flt, filterSize, analogRead(input->pin));
@ -222,10 +235,10 @@ void processPedal(struct Pedal* input, SignalFilter *flt, uint8_t filterSize)
// calibrate, we want the highest this pedal has been
input->max = input->cur > input->max ? input->cur : input->max;
// same for lowest, but bottom out at current value rather than 0
input->min = input->min == 0 || input->cur < input->min ? input->cur : input->min;
input->min = input->cur < input->min ? input->cur : input->min;
}
input->axis = axisValue(input);
input->axis = axisValue(input, dead_zone);
}
void setXAxis(void* in) {
@ -327,7 +340,7 @@ int getCurrentGear(int shifterPosition[], int btns[]) {
}
} else if ( x >= calibration.data.shifter_x_56 )
{
uint8_t reverse = (calibration.data.flags & FLAG_REVERSE_RIGHT_RED) ? btns[BUTTON_RED_RIGHT] : btns[BUTTON_REVERSE];
uint8_t reverse = (calibration.data.flag1 & FLAG1_REVERSE_RIGHT_RED) ? btns[BUTTON_RED_RIGHT] : btns[BUTTON_REVERSE];
if(reverse)
{
if( gear != 4 && gear != 6 ) /* avoid toggles between neighboring gears */
@ -393,6 +406,26 @@ void setButtonStates(int buttons[], int gear) {
}
}
void set_dead_zone(uint8_t dz, int pedal, CalibData *calib)
{
dz /= 2;
switch(pedal)
{
case 0:
calib->flag2 &= ~(FLAG2_GAS_DEAD_ZONE);
calib->flag2 |= (dz) << 4;
break;
case 1:
calib->flag2 &= ~(FLAG2_BRAKE_DEAD_ZONE);
calib->flag2 |= (dz) << 1;
break;
case 2:
calib->flag3 &= ~(FLAG3_CLUTCH_DEAD_ZONE);
calib->flag3 |= (dz) << 4;
break;
}
}
#define CALIB_MIN(calibValue, curValue, minValue) if( calibValue < 0 || curValue < minValue ) { calibValue = minValue = curValue; }
#define CALIB_MAX(calibValue, curValue, maxValue) if( calibValue < 0 || curValue > maxValue ) { calibValue = maxValue = curValue; }
#define CALIB_RANGE(calibValue, curValue, minValue, maxValue) \
@ -439,6 +472,20 @@ void calib(struct Pedal *gas, Pedal *brake, Pedal *clutch, int shifter_X, int sh
SET_SHIFTER_FILTSIZE_7 = '6',
SET_SHIFTER_FILTSIZE_9 = '8',
SET_SHIFTER_FILTSIZE_15 = 'F',
SET_COMBINE_Z_EQUAL_X_MINUS_Z = '+',
SET_COMBINE_Z_EQUAL_Z_MINUS_X = '-',
SET_COMBINE_Z_EQUAL_Z = '.',
SET_DEAD_ZONE00 = '^',
SET_DEAD_ZONE02 = '!',
SET_DEAD_ZONE04 = '"',
SET_DEAD_ZONE06 = ']',
SET_DEAD_ZONE08 = '$',
SET_DEAD_ZONE10 = '%',
SET_DEAD_ZONE12 = '&',
SET_DEAD_ZONE14 = '/',
SELECT_BRAKE_DEAD_ZONE = '(',
SELECT_CLUTCH_DEAD_ZONE = ')',
SELECT_GAS_DEAD_ZONE = '[',
SET_PRINT_MODE = 'O',
RESET_PRINT_MODE = 'o',
STORE_CALIB = 'w',
@ -446,6 +493,7 @@ void calib(struct Pedal *gas, Pedal *brake, Pedal *clutch, int shifter_X, int sh
EEPROM_CALIB = 'U'
} currentMode = IDLE;
static int calibValue = -1;
static int deadZoneSelect = -1;
if (Serial.available() > 0)
{
char rx_byte = Serial.read();
@ -464,20 +512,20 @@ void calib(struct Pedal *gas, Pedal *brake, Pedal *clutch, int shifter_X, int sh
case SET_PEDAL_AUTO_CALIBRATE: calibration.data.pedals_auto_calib = 1; break;
case RESET_PEDAL_AUTO_CALIBRATE: calibration.data.pedals_auto_calib= 0; break;
case SET_PEDALS_ENABLED: calibration.data.use_pedals = 1; break;
case RESET_PEDALS_ENABLED: calibration.data.use_pedals = 0; break;
case SET_PEDALS_ENABLED: calibration.data.flag2 |= FLAG2_ENABLE_PEDALS; break;
case RESET_PEDALS_ENABLED: calibration.data.flag2 &= ~FLAG2_ENABLE_PEDALS; break;
case SET_SHIFTER_ENABLED: calibration.data.use_shifter = 1; break;
case RESET_SHIFTER_ENABLED: calibration.data.use_shifter = 0; break;
case SET_SHIFTER_ENABLED: calibration.data.flag3 |= FLAG3_ENABLE_SHIFTER; break;
case RESET_SHIFTER_ENABLED: calibration.data.flag3 &= ~FLAG3_ENABLE_SHIFTER; break;
case SET_GAS_INVERTED: calibration.data.flags |= FLAG_INVERT_GAS; break;
case RESET_GAS_INVERTED: calibration.data.flags &= ~FLAG_INVERT_GAS; break;
case SET_BRAKE_INVERTED: calibration.data.flags |= FLAG_INVERT_BRAKE; break;
case RESET_BRAKE_INVERTED: calibration.data.flags &= ~FLAG_INVERT_BRAKE; break;
case SET_CLUTCH_INVERTED: calibration.data.flags |= FLAG_INVERT_CLUTCH; break;
case RESET_CLUTCH_INVERTED: calibration.data.flags &= ~FLAG_INVERT_CLUTCH; break;
case SET_REVERSE_RIGHT_RED: calibration.data.flags |= FLAG_REVERSE_RIGHT_RED; break;
case RESET_REVERSE_RIGHT_RED: calibration.data.flags &= ~FLAG_REVERSE_RIGHT_RED; break;
case SET_GAS_INVERTED: calibration.data.flag1 |= FLAG1_INVERT_GAS; break;
case RESET_GAS_INVERTED: calibration.data.flag1 &= ~FLAG1_INVERT_GAS; break;
case SET_BRAKE_INVERTED: calibration.data.flag1 |= FLAG1_INVERT_BRAKE; break;
case RESET_BRAKE_INVERTED: calibration.data.flag1 &= ~FLAG1_INVERT_BRAKE; break;
case SET_CLUTCH_INVERTED: calibration.data.flag1 |= FLAG1_INVERT_CLUTCH; break;
case RESET_CLUTCH_INVERTED: calibration.data.flag1 &= ~FLAG1_INVERT_CLUTCH; break;
case SET_REVERSE_RIGHT_RED: calibration.data.flag1 |= FLAG1_REVERSE_RIGHT_RED; break;
case RESET_REVERSE_RIGHT_RED: calibration.data.flag1 &= ~FLAG1_REVERSE_RIGHT_RED; break;
case SET_PEDAL_FILTSIZE_OFF: calibration.data.pedal_median_size = 0; break;
case SET_PEDAL_FILTSIZE_3: calibration.data.pedal_median_size = 3; break;
@ -493,6 +541,20 @@ void calib(struct Pedal *gas, Pedal *brake, Pedal *clutch, int shifter_X, int sh
case SET_SHIFTER_FILTSIZE_9: calibration.data.shifter_median_size = 15; break;
case SET_SHIFTER_FILTSIZE_15: calibration.data.shifter_median_size = 49; break;
case SET_COMBINE_Z_EQUAL_X_MINUS_Z: calibration.data.flag1 &= ~(FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X); calibration.data.flag1 |= FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z; break;
case SET_COMBINE_Z_EQUAL_Z_MINUS_X: calibration.data.flag1 &= ~(FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z); calibration.data.flag1 |= FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X; break;
case SET_COMBINE_Z_EQUAL_Z: calibration.data.flag1 &= ~(FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X|FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z); break;
case SET_DEAD_ZONE00: set_dead_zone(0, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE02: set_dead_zone(2, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE04: set_dead_zone(4, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE06: set_dead_zone(6, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE08: set_dead_zone(8, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE10: set_dead_zone(10, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE12: set_dead_zone(12, deadZoneSelect, &calibration.data); break;
case SET_DEAD_ZONE14: set_dead_zone(14, deadZoneSelect, &calibration.data); break;
case SELECT_BRAKE_DEAD_ZONE: deadZoneSelect = 1; break;
case SELECT_CLUTCH_DEAD_ZONE: deadZoneSelect = 2; break;
case SELECT_GAS_DEAD_ZONE: deadZoneSelect = 0; break;
case SET_PRINT_MODE: printMode = 1; break;
case RESET_PRINT_MODE: printMode = 0;; break;
@ -612,27 +674,42 @@ SignalFilter signalFilters[5];
void loop() {
debug.profiling[2] = micros();
// pedals
processPedal(gasPedal, &signalFilters[0], calibration.data.pedal_median_size);
processPedal(brakePedal, &signalFilters[1], calibration.data.pedal_median_size);
processPedal(clutchPedal, &signalFilters[2], calibration.data.pedal_median_size);
processPedal(gasPedal, &signalFilters[0], calibration.data.pedal_median_size,
((calibration.data.flag2 & FLAG2_GAS_DEAD_ZONE) >> 4)*2);
processPedal(brakePedal, &signalFilters[1], calibration.data.pedal_median_size,
((calibration.data.flag2 & FLAG2_BRAKE_DEAD_ZONE) >> 1)*2);
processPedal(clutchPedal, &signalFilters[2], calibration.data.pedal_median_size,
((calibration.data.flag3 & FLAG3_CLUTCH_DEAD_ZONE) >> 4)*2);
if(calibration.data.flags & FLAG_INVERT_GAS )
if(calibration.data.flag1 & FLAG1_INVERT_GAS )
{
Pedal* gas = (Pedal*)gasPedal;
gas->axis = map(gas->axis, 0, MAX_AXIS, MAX_AXIS, 0);
}
if(calibration.data.flags & FLAG_INVERT_BRAKE )
if(calibration.data.flag1 & FLAG1_INVERT_BRAKE )
{
Pedal* brake = (Pedal*)brakePedal;
brake->axis = map(brake->axis, 0, MAX_AXIS, MAX_AXIS, 0);
}
if(calibration.data.flags & FLAG_INVERT_CLUTCH )
if(calibration.data.flag1 & FLAG1_INVERT_CLUTCH )
{
Pedal* clutch = (Pedal*)clutchPedal;
clutch->axis = map(clutch->axis, 0, MAX_AXIS, MAX_AXIS, 0);
}
if(calibration.data.flag1 & FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z)
{
Pedal *clutch = (Pedal*)clutchPedal;
Pedal *gas = (Pedal*)gasPedal;
clutch->axis = map(gas->axis - clutch->axis, -MAX_AXIS, MAX_AXIS, 0, MAX_AXIS);
}
if(calibration.data.flag1 & FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X)
{
Pedal *clutch = (Pedal*)clutchPedal;
Pedal *gas = (Pedal*)gasPedal;
clutch->axis = map(clutch->axis - gas->axis, -MAX_AXIS, MAX_AXIS, 0, MAX_AXIS);
}
if(calibration.data.use_pedals)
if(calibration.data.flag2 & FLAG2_ENABLE_PEDALS)
{
setXAxis(gasPedal);
setYAxis(brakePedal);
@ -658,7 +735,7 @@ void loop() {
int gear = getCurrentGear(shifterPosition, buttonStates);
if(calibration.data.use_shifter)
if(calibration.data.flag3 & FLAG3_ENABLE_SHIFTER)
{
setButtonStates(buttonStates, gear);
} else

View File

@ -2,6 +2,7 @@ import struct
import ctypes as ct
import sys
import time
import os
import traceback
from PySide2.QtCore import QRectF, Qt, QObject, QThread, Signal, QMutex, QMutexLocker, QTimer, QSignalBlocker
from PySide2.QtGui import QBrush, QPen, QColor
@ -16,10 +17,17 @@ import numpy as np
# port.
import inputs
FLAG_INVERT_BRAKE = 0x1
FLAG_INVERT_GAS = 0x2
FLAG_INVERT_CLUTCH = 0x4
FLAG_REVERSE_RIGHT_RED = 0x8
FLAG1_INVERT_BRAKE = 0x1
FLAG1_INVERT_GAS = 0x2
FLAG1_INVERT_CLUTCH = 0x4
FLAG1_REVERSE_RIGHT_RED = 0x8
FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z = 0x10
FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X = 0x20
FLAG2_ENABLE_PEDALS = 0x1
FLAG2_BRAKE_DEAD_ZONE = (0x2|0x4|0x8)
FLAG2_GAS_DEAD_ZONE = (0x10|0x20|0x40)
FLAG3_ENABLE_SHIFTER = 0x1
FLAG3_CLUTCH_DEAD_ZONE = (0x10|0x20|0x40)
# following structures need to be synchronized with Arduino C Code
class CalibData(ct.Structure):
@ -27,9 +35,9 @@ class CalibData(ct.Structure):
_fields_ = [
("calibID", ct.c_uint32),
("pedals_auto_calib", ct.c_uint8),
("flags", ct.c_uint8),
("use_pedals", ct.c_uint8),
("use_shifter", ct.c_uint8),
("flag1", ct.c_uint8),
("flag2", ct.c_uint8),
("flag3", ct.c_uint8),
("pedals_median_size", ct.c_uint8),
("shifter_median_size", ct.c_uint8),
("gasMin", ct.c_uint16),
@ -161,26 +169,39 @@ class G27CalibGui(QWidget):
"Use right red button for reverse instead pushing the gear",
"Enable pedals",
"Enable shifter"]
] + [QComboBox(), QComboBox()]
self.option_cmds = [(b"p", b"P"),
(b"y", b"Y"),
(b"x", b"X"),
(b"z", b"Z"),
(b"q", b"Q"),
(b"e", b"E"),
(b"s", b"S"),
] + [QComboBox(), QComboBox(), QComboBox(), QComboBox(), QComboBox(), QComboBox()]
self.option_cmds = [(b"p", b"P"), #0
(b"y", b"Y"), #1
(b"x", b"X"), #2
(b"z", b"Z"), #3
(b"q", b"Q"), #4
(b"e", b"E"), #5
(b"s", b"S"), #6
(b".", b"+", b"-"), #7
(b"[^", b"[!", b"[\"", b"[]", b"[$", b"[%", b"[&", b"[/"),
(b"(^", b"(!", b"(\"", b"(]", b"($", b"(%", b"(&", b"(/"),
(b")^", b")!", b")\"", b")]", b")$", b")%", b")&", b")/"),
(b"0", b"3", b"5", b"7", b"9", b"f"),
(b"1", b"2", b"4", b"6", b"8", b"F"),
]
self.option_btns[-6].addItem("Do not combine clutch and gas")
self.option_btns[-6].addItem("Combine Clutch and Gas (Clutch = Gas - Clutch)")
self.option_btns[-6].addItem("Combine Clutch and Gas (Clutch = Clutch - Gas)")
for (idx, name) in [(-5, "Gas"), (-4, "Brake"), (-3, "Clutch")]:
for dz in [0,2,4,6,8,10,12,14]:
self.option_btns[idx].addItem("%s: %d%% dead zone" % (name, dz))
for (idx, name) in [(-2, "pedals"), (-1, "shifter")]:
for size in [0,3,5,9,15,49]:
self.option_btns[idx].addItem("off" if size == 0 else (str(size) + "-median"), size)
for i,b in enumerate(self.option_btns):
n_checkboxes = len(self.option_cmds) - 2
n_checkboxes = len(self.option_cmds) - 6
if i < n_checkboxes:
grid.addWidget(b, i, 0, 1, 2)
else:
grid.addWidget(QLabel("Pedal filter" if i == n_checkboxes else "Shifter filter", parent=self), i, 0)
names = {n_checkboxes: "Combine",
n_checkboxes + 1: "Gas Dead Zone", n_checkboxes + 2: "Brake Dead Zone", n_checkboxes + 3: "Clutch Dead Zone",
n_checkboxes + 4: "Pedal filter", n_checkboxes + 5: "Shifter filter"}
grid.addWidget(QLabel(names[i], parent=self), i, 0)
grid.addWidget(b, i, 1)
if isinstance(b, QCheckBox):
b.toggled.connect(self.optionChanged)
@ -300,14 +321,23 @@ class G27CalibGui(QWidget):
for b in self.option_btns:
blockers.append(QSignalBlocker(b))
self.option_btns[0].setChecked(values.calib.pedals_auto_calib)
self.option_btns[1].setChecked((values.calib.flags & FLAG_INVERT_GAS) != 0)
self.option_btns[2].setChecked((values.calib.flags & FLAG_INVERT_BRAKE) != 0)
self.option_btns[3].setChecked((values.calib.flags & FLAG_INVERT_CLUTCH) != 0)
self.option_btns[4].setChecked((values.calib.flags & FLAG_REVERSE_RIGHT_RED) != 0)
self.option_btns[5].setChecked(values.calib.use_pedals)
self.option_btns[6].setChecked(values.calib.use_shifter)
self.option_btns[7].setCurrentIndex(self.option_btns[7].findData(values.calib.pedals_median_size))
self.option_btns[8].setCurrentIndex(self.option_btns[8].findData(values.calib.shifter_median_size))
self.option_btns[1].setChecked((values.calib.flag1 & FLAG1_INVERT_GAS) != 0)
self.option_btns[2].setChecked((values.calib.flag1 & FLAG1_INVERT_BRAKE) != 0)
self.option_btns[3].setChecked((values.calib.flag1 & FLAG1_INVERT_CLUTCH) != 0)
self.option_btns[4].setChecked((values.calib.flag1 & FLAG1_REVERSE_RIGHT_RED) != 0)
self.option_btns[5].setChecked((values.calib.flag2 & FLAG2_ENABLE_PEDALS) != 0)
self.option_btns[6].setChecked((values.calib.flag3 & FLAG3_ENABLE_SHIFTER) != 0)
if (values.calib.flag1 & (FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z | FLAG1_COMBINE_Z_EQUALS_Z_MINUS_X)) == 0:
self.option_btns[7].setCurrentIndex(0)
elif (values.calib.flag1 & FLAG1_COMBINE_Z_EQUALS_X_MINUS_Z) != 0:
self.option_btns[7].setCurrentIndex(1)
else:
self.option_btns[7].setCurrentIndex(2)
self.option_btns[8].setCurrentIndex((values.calib.flag2 & FLAG2_GAS_DEAD_ZONE) >> 4)
self.option_btns[9].setCurrentIndex((values.calib.flag2 & FLAG2_BRAKE_DEAD_ZONE) >> 1)
self.option_btns[10].setCurrentIndex((values.calib.flag3 & FLAG3_CLUTCH_DEAD_ZONE) >> 4)
self.option_btns[11].setCurrentIndex(self.option_btns[11].findData(values.calib.pedals_median_size))
self.option_btns[12].setCurrentIndex(self.option_btns[12].findData(values.calib.shifter_median_size))
prof = "Total runtime: %9.2f ms | prof[0->1]: %9.2f ms | prof[1->2]: %9.2f ms | prof[2->3]: %9.2f ms | FPS: %04d" % (
(dbg.profiling[-1] - dbg.profiling[0])*1e-3,
@ -353,6 +383,12 @@ class Collector(QObject):
def sendModeCmd(self, cmd):
self.serialPort.write(cmd)
#print("Sent CMD: ", cmd)
def stop(self):
print("Disabling serial monitor.")
self.serialPort.write(b'o')
self.timer.stop()
self.thread.quit()
def create(self):
try:
@ -408,6 +444,10 @@ class JoystickSink(QObject):
self.timer.timeout.connect(self.readFromDevice, Qt.QueuedConnection)
self.timer.setInterval(0)
self.timer.start()
def stop(self):
self.timer.stop()
self.thread.quit()
def readFromDevice(self):
try:
@ -426,8 +466,10 @@ def main():
gui.setWindowTitle("G27 Pedalsand Shifter")
coll = Collector(vars["tty"])
coll.valuesChanged.connect(gui.newVals)
app.aboutToQuit.connect(coll.stop)
if vars["jsdev"] is not None:
js = JoystickSink(vars["jsdev"])
app.aboutToQuit.connect(js.stop)
else:
js = None
gui.sendModeCmd.connect(coll.sendModeCmd)
@ -477,7 +519,7 @@ def main():
vars["tty"] = list_ports.comports()[0].device
vars["jsdev"] = inputs.devices.gamepads[0]
createGui()
return app.exec_()
os._exit(app.exec_())
if __name__ == "__main__":
main()