observable connect
This commit is contained in:
parent
24b88da023
commit
b1d10fe3b1
|
@ -1 +1,4 @@
|
|||
## modbus
|
||||
## Работа с роботом
|
||||
|
||||
### Тестовое окружение
|
||||
* `poetry run python main.py --mode test`
|
|
@ -0,0 +1,26 @@
|
|||
2024-10-25 09:35:09,819 - logger - INFO - test
|
||||
2024-10-25 09:35:13,350 - logger - INFO - test
|
||||
2024-10-25 10:32:36,506 - logger - INFO - not_connected
|
||||
2024-10-25 10:39:48,747 - logger - INFO - not_connected
|
||||
2024-10-25 10:42:35,337 - logger - INFO - not_connected
|
||||
2024-10-25 10:42:36,287 - logger - INFO - not_connected
|
||||
2024-10-25 10:42:37,541 - logger - INFO - connected
|
||||
2024-10-25 10:42:38,252 - logger - INFO - connected
|
||||
2024-10-25 10:42:39,252 - logger - INFO - connected
|
||||
2024-10-25 10:42:40,253 - logger - INFO - connected
|
||||
2024-10-25 10:42:41,253 - logger - INFO - connected
|
||||
2024-10-25 10:42:42,253 - logger - INFO - connected
|
||||
2024-10-25 10:42:43,252 - logger - INFO - connected
|
||||
2024-10-25 10:42:44,253 - logger - INFO - connected
|
||||
2024-10-25 10:42:45,252 - logger - INFO - connected
|
||||
2024-10-25 10:43:37,355 - logger - INFO - Value changed: not_connected
|
||||
2024-10-25 10:43:40,252 - logger - INFO - Value changed: connected
|
||||
2024-10-25 10:43:43,595 - logger - INFO - Value changed: not_connected
|
||||
2024-10-25 10:53:29,935 - logger - INFO - Value changed: not_connected
|
||||
2024-10-25 10:53:41,824 - logger - INFO - Value changed: not_connected
|
||||
2024-10-25 10:53:45,860 - logger - INFO - Value changed: connected
|
||||
2024-10-25 10:53:50,752 - logger - INFO - Value changed: not_connected
|
||||
2024-10-25 10:53:52,751 - logger - INFO - Value changed: connected
|
||||
2024-10-25 10:53:54,993 - logger - INFO - Value changed: not_connected
|
||||
2024-10-25 10:53:57,014 - logger - INFO - Value changed: connected
|
||||
2024-10-25 10:54:02,382 - logger - INFO - Value changed: not_connected
|
44
gui/init.py
44
gui/init.py
|
@ -5,6 +5,9 @@ from PyQt5.QtGui import QColor, QPalette
|
|||
from gui.robot import ChangeRobot
|
||||
from gui.status import Status
|
||||
from gui.imitator import Imitator
|
||||
from gui.visualize import Visualize
|
||||
from gui.observable import Observable
|
||||
from logger import logger
|
||||
|
||||
|
||||
class RightPanel(QWidget):
|
||||
|
@ -12,7 +15,6 @@ class RightPanel(QWidget):
|
|||
super().__init__()
|
||||
layout = QVBoxLayout()
|
||||
for panel in panels:
|
||||
# panel.setFixedHeight(200)
|
||||
layout.addWidget(panel)
|
||||
self.setLayout(layout)
|
||||
self.initUI()
|
||||
|
@ -25,8 +27,11 @@ class RightPanel(QWidget):
|
|||
|
||||
|
||||
class MainPanel(QWidget):
|
||||
def __init__(self):
|
||||
def __init__(self, panels):
|
||||
super().__init__()
|
||||
layout = QVBoxLayout()
|
||||
for panel in panels:
|
||||
layout.addWidget(panel)
|
||||
self.initUI()
|
||||
|
||||
def initUI(self):
|
||||
|
@ -40,20 +45,33 @@ class MainContentComponent(QWidget):
|
|||
def __init__(self, **kwargs):
|
||||
super().__init__()
|
||||
|
||||
self.observable = Observable(kwargs.get("get_status"))
|
||||
self.observable.value_changed.connect(self.handle_value_change)
|
||||
|
||||
robotArgs = kwargs.get("robotPanel", {})
|
||||
robotPanel = ChangeRobot(**robotArgs)
|
||||
self.robotPanel = ChangeRobot(**robotArgs)
|
||||
|
||||
statusArgs = kwargs.get("statusPanel", {})
|
||||
statusPanel = Status(**statusArgs)
|
||||
self.statusPanel = Status(**statusArgs)
|
||||
|
||||
imitatorArgs = kwargs.get("imitatorPanel", {})
|
||||
imitatorPanel = Imitator(**imitatorArgs)
|
||||
self.imitatorPanel = Imitator(**imitatorArgs)
|
||||
|
||||
self.rightPanel = RightPanel(
|
||||
panels=[
|
||||
statusPanel,
|
||||
robotPanel,
|
||||
imitatorPanel
|
||||
self.statusPanel,
|
||||
self.robotPanel,
|
||||
self.imitatorPanel,
|
||||
]
|
||||
)
|
||||
|
||||
visArgs = kwargs.get("visPanel", {})
|
||||
self.visPanel = Visualize(**visArgs)
|
||||
self.mainPanel = MainPanel(
|
||||
panels=[
|
||||
self.visPanel,
|
||||
]
|
||||
)
|
||||
self.mainPanel = MainPanel()
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.addWidget(self.mainPanel)
|
||||
|
@ -74,6 +92,14 @@ class MainContentComponent(QWidget):
|
|||
self.rightPanel.setFixedWidth(rightPanelWidth)
|
||||
super().resizeEvent(event)
|
||||
|
||||
def handle_value_change(self, new_value):
|
||||
logger.info(f"Value changed: {new_value}")
|
||||
|
||||
if new_value == "not_connected":
|
||||
self.imitatorPanel.setDisabled(True)
|
||||
if new_value == "connected":
|
||||
self.imitatorPanel.setDisabled(False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
from PyQt5.QtCore import pyqtSignal, QObject, QTimer
|
||||
from logger import logger
|
||||
|
||||
class Observable(QObject):
|
||||
value_changed = pyqtSignal(object) # Сигнал с переданным значением
|
||||
|
||||
def __init__(self, func, interval=1000):
|
||||
super().__init__()
|
||||
self.get_dynamic_value = func
|
||||
self._value = None
|
||||
|
||||
# Таймер для периодической проверки значения
|
||||
self.timer = QTimer(self)
|
||||
self.timer.timeout.connect(self.check_function) # Вызываем some_function на каждом таймере
|
||||
self.timer.start(interval) # Интервал в миллисекундах
|
||||
|
||||
def check_function(self):
|
||||
# Пример функции, которая обновляет значение
|
||||
new_value = self.get_dynamic_value()
|
||||
if new_value != self._value:
|
||||
self._value = new_value
|
||||
self.value_changed.emit(new_value)
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy
|
||||
from PyQt5.QtGui import QImage, QPixmap
|
||||
from PyQt5.QtCore import QTimer
|
||||
|
||||
class Visualize(QWidget):
|
||||
def __init__(self, get_pybullet_image):
|
||||
super().__init__()
|
||||
self.get_pybullet_image = get_pybullet_image
|
||||
|
||||
# Настройка компоновки
|
||||
self.layout = QVBoxLayout(self)
|
||||
self.layout.setContentsMargins(0, 0, 0, 0) # Убираем отступы по краям
|
||||
self.label = QLabel(self)
|
||||
self.label.setScaledContents(True) # Масштабирование изображения по размеру QLabel
|
||||
self.label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # QLabel занимает всю доступную область
|
||||
self.layout.addWidget(self.label)
|
||||
|
||||
# Таймер для обновления изображения
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.update_image)
|
||||
self.timer.start(100) # Обновление каждые 100 мс
|
||||
|
||||
def update_image(self):
|
||||
(rgb, width, height) = self.get_pybullet_image()
|
||||
|
||||
# Преобразование RGB-данных в QImage
|
||||
image = QImage(rgb, width, height, QImage.Format_RGB888)
|
||||
pixmap = QPixmap.fromImage(image)
|
||||
|
||||
# Обновление изображения на QLabel
|
||||
self.label.setPixmap(pixmap)
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import sys
|
||||
import logging
|
||||
|
||||
# Настройка логгера
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG, # Уровень логирования
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
handlers=[
|
||||
logging.FileHandler("app.log"), # Запись в файл
|
||||
logging.StreamHandler(sys.stdout), # Вывод в консоль
|
||||
],
|
||||
)
|
||||
|
||||
logger = logging.getLogger("logger")
|
22
main.py
22
main.py
|
@ -1,17 +1,20 @@
|
|||
import json
|
||||
import sys
|
||||
import time
|
||||
import argparse
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
|
||||
from robot.client_socket import SocketRobotArm
|
||||
from gui.init import MainContentComponent
|
||||
from logger import logger
|
||||
|
||||
|
||||
class MyApp:
|
||||
with open("./robots.json", "r") as file:
|
||||
robots = json.load(file)
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, mode):
|
||||
self.mode = mode
|
||||
self.startRobot()
|
||||
self.startGui()
|
||||
|
||||
|
@ -27,6 +30,7 @@ class MyApp:
|
|||
def startGui(self):
|
||||
app = QApplication(sys.argv)
|
||||
mainWindow = MainContentComponent(
|
||||
get_status=self.get_status,
|
||||
robotPanel={
|
||||
"robots": self.robots,
|
||||
"updateRobot": self.updateRobot,
|
||||
|
@ -41,6 +45,9 @@ class MyApp:
|
|||
"command_count": self.robot_app.get_command_count,
|
||||
"updateData": self.robot_app.upd_model,
|
||||
},
|
||||
visPanel={
|
||||
"get_pybullet_image": self.robot_app.get_pybullet_image,
|
||||
},
|
||||
)
|
||||
mainWindow.setWindowTitle("ROBOT GUI")
|
||||
mainWindow.show()
|
||||
|
@ -53,6 +60,7 @@ class MyApp:
|
|||
def updateRobot(self, robot):
|
||||
if robot in self.robots:
|
||||
selected_robot = robot
|
||||
if self.mode == "test":
|
||||
selected_robot = {"name": "test", "host": "127.0.0.1", "slave_id": 11}
|
||||
|
||||
if self.robot_app.status == "connected":
|
||||
|
@ -65,4 +73,14 @@ class MyApp:
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
MyApp()
|
||||
parser = argparse.ArgumentParser(description="MyApp Command Line Interface")
|
||||
parser.add_argument(
|
||||
"--mode",
|
||||
type=str,
|
||||
choices=["test", "prod"],
|
||||
default="prod",
|
||||
help="Mode of operation",
|
||||
)
|
||||
# MyApp()
|
||||
args = parser.parse_args()
|
||||
app = MyApp(args.mode)
|
||||
|
|
|
@ -61,6 +61,23 @@ class SocketRobotArm:
|
|||
useFixedBase=True,
|
||||
)
|
||||
|
||||
def get_pybullet_image(self):
|
||||
width, height, rgb, _, _ = p.getCameraImage(
|
||||
width=320,
|
||||
height=240,
|
||||
viewMatrix=p.computeViewMatrix(
|
||||
cameraEyePosition=[1, 1, 1],
|
||||
cameraTargetPosition=[0, 0, 0],
|
||||
cameraUpVector=[0, 0, 1],
|
||||
),
|
||||
projectionMatrix=p.computeProjectionMatrixFOV(
|
||||
fov=60.0, aspect=1.0, nearVal=0.1, farVal=10.0
|
||||
),
|
||||
renderer=p.ER_BULLET_HARDWARE_OPENGL,
|
||||
physicsClientId=self.physics_client,
|
||||
)
|
||||
return (rgb, width, height)
|
||||
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
self.socket = None
|
||||
|
|
Loading…
Reference in New Issue