Odrive control using PyQt joystick

Hi there!

I wrote a code for the joystick using PyQt 5. It’s very simple, but it’s enough for my task. Now I’m trying to make a deal with Odrive to control the thrusters.
My scheme:
Orange Pi 5 Plus with Ubuntu
Joystick.py
Odrive 3.6
Thruster #1
Thruster #2

Has anyone tried this before?

Here is the code:

from PyQt5.QtWidgets import QWidget
from PyQt5.Qt import *
import sys
from enum import Enum

class Direction(Enum):
Left = 0
Right = 1
Up = 2
Down = 3

class Joystick(QWidget):
def init(self, parent=None):
super(Joystick, self).init(parent)
self.setMinimumSize(100, 100)
self.movingOffset = QPointF(0, 0)
self.grabCenter = False
self.__maxDistance = 50

def paintEvent(self, event):
    painter = QPainter(self)
    bounds = QRectF(-self.__maxDistance, -self.__maxDistance, self.__maxDistance * 2, self.__maxDistance * 2).translated(self._center())
    painter.drawEllipse(bounds)
    painter.setBrush(Qt.black)
    painter.drawEllipse(self._centerEllipse())

def _centerEllipse(self):
    if self.grabCenter:
        return QRectF(-20, -20, 40, 40).translated(self.movingOffset)
    return QRectF(-20, -20, 40, 40).translated(self._center())

def _center(self):
    return QPointF(self.width()/2, self.height()/2)


def _boundJoystick(self, point):
    limitLine = QLineF(self._center(), point)
    if (limitLine.length() > self.__maxDistance):
        limitLine.setLength(self.__maxDistance)
    return limitLine.p2()

def joystickDirection(self):
    if not self.grabCenter:
        return 0
    normVector = QLineF(self._center(), self.movingOffset)
    currentDistance = normVector.length()
    angle = normVector.angle()

    distance = min(currentDistance / self.__maxDistance, 1.0)
    if 45 <= angle < 135:
        return (Direction.Up, distance)
    elif 135 <= angle < 225:
        return (Direction.Left, distance)
    elif 225 <= angle < 315:
        return (Direction.Down, distance)
    return (Direction.Right, distance)


def mousePressEvent(self, ev):
    self.grabCenter = self._centerEllipse().contains(ev.pos())
    return super().mousePressEvent(ev)

def mouseReleaseEvent(self, event):
    self.grabCenter = False
    self.movingOffset = QPointF(0, 0)
    self.update()

def mouseMoveEvent(self, event):
    if self.grabCenter:
        print("Moving")
        self.movingOffset = self._boundJoystick(event.pos())
        self.update()
    print(self.joystickDirection())

if name == ‘main’:
# Create main application window
app = QApplication()
app.setStyle(QStyleFactory.create(“Cleanlooks”))
mw = QMainWindow()
mw.setWindowTitle(‘Joystick’)

# Create and set widget layout
# Main widget container
cw = QWidget()
ml = QGridLayout()
cw.setLayout(ml)
mw.setCentralWidget(cw)

# Create joystick 
joystick = Joystick()

# ml.addLayout(joystick.get_joystick_layout(),0,0)
ml.addWidget(joystick,0,0)

mw.show()

## Start Qt event loop unless running in interactive mode or using pyside.
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
    QApplication.instance().exec_()