Skip to content

Commit 8820b7f

Browse files
committed
Added release: 0.9.2
1 parent 27e66c2 commit 8820b7f

File tree

146 files changed

+772831
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+772831
-5
lines changed

.gitignore

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ build/
1212
develop-eggs/
1313
dist/
1414
downloads/
15+
mp4/
1516
eggs/
1617
.eggs/
17-
lib/
18-
lib64/
1918
parts/
2019
sdist/
2120
var/
@@ -31,7 +30,6 @@ MANIFEST
3130
# Usually these files are written by a python script from a template
3231
# before PyInstaller builds the exe, so as to inject date/other infos into it.
3332
*.manifest
34-
*.spec
3533

3634
# Installer logs
3735
pip-log.txt
@@ -70,6 +68,10 @@ instance/
7068

7169
# Sphinx documentation
7270
docs/_build/
71+
docs/build/
72+
73+
# PyCharm
74+
.idea/
7375

7476
# PyBuilder
7577
target/

CHANGELOG.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
0.9.2 (2023.03.27)
2+
3+
- fixed wrong delta to angle Y axis calculation
4+
- fixed clients list parsing on config save
5+
- added GPU support to Windows version
6+
- added webstream connections
7+
- added overlay labels
8+
- added continous and toggle actions control via keyboard
9+
- added window UI sliders
10+
- added logo, website url and updater
11+
12+
----
13+
14+
0.9.1 (2023.03.21)
15+
16+
- fixed connection core between sockets
17+
- fixed high CPU usage after remote disconnect
18+
- fixed serial port disconnect handling
19+
- added ping and socket responses for device commands
20+
- added performance debug info
21+
- added options tab
22+
- added config save option
23+
24+
----
25+
26+
0.9.0 (2023.03.14)
27+
28+
- initial beta version

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
1-
# server
2-
[Python] Desktop Server Application (PC, Windows, Linux)
1+
# SERVO CAM - Server Desktop App (PC)
2+
3+
## This repository is a part of SERVO CAM project.
4+
5+
![logo2](https://user-images.githubusercontent.com/129175238/228258366-c533475f-4e44-4717-a9ee-2ba5df2818e1.png)
6+
7+
Project website: https://servocam.org
8+
9+
Documentation (en): https://servo-cam.readthedocs.io/en/latest
10+
11+
GitHub: https://github.com/servo-cam
12+
13+
Release: **0.9.2** | 2023.03.27
14+
15+
------
16+
(c) 2023, servocam.org
17+
18+
MIT License

__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# =============================================================================
4+
# This file is a part of servocam.org package <servocam.org>
5+
# Created By: Marcin Szczygliński <info@servocam.org>
6+
# GitHub: https://github.com/servo-cam
7+
# License: MIT
8+
# Updated At: 2023.03.27 02:00
9+
# =============================================================================
10+
11+
__author__ = "Marcin Szczygliński"
12+
__copyright__ = "(c) 2023, servocam.org"
13+
__credits__ = ["servocam.org"]
14+
__version__ = "0.9.2"
15+
__build__ = "2023.03.27"
16+
__maintainer__ = "Marcin Szczygliński"
17+
__email__ = "info@servocam.org"
18+
__www__ = "https://servocam.org"
19+
__license__ = "MIT"
20+
__status__ = "Development"

app.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# =============================================================================
4+
# This file is a part of servocam.org package <servocam.org>
5+
# Created By: Marcin Szczygliński <info@servocam.org>
6+
# GitHub: https://github.com/servo-cam
7+
# License: MIT
8+
# Updated At: 2023.03.27 02:00
9+
# =============================================================================
10+
11+
12+
import sys
13+
import numpy as np
14+
from PySide6.QtCore import QTimer, Slot
15+
from PySide6.QtGui import QScreen
16+
from PySide6.QtWidgets import (QApplication, QMainWindow)
17+
from core.tracker import Tracker
18+
from core.ui.main import UI
19+
from core.threads import RemoteVideoThread, SocketThread, StatusThread
20+
21+
22+
class MainWindow(QMainWindow):
23+
24+
def __init__(self):
25+
"""App main window"""
26+
super().__init__()
27+
self.tracker = Tracker(self)
28+
self.timer = None
29+
30+
# setup UI
31+
self.ui = UI(self)
32+
self.ui.setup()
33+
34+
# load model
35+
self.tracker.controller.internals.toggle_model(self.tracker.model_name)
36+
37+
# init app
38+
self.setup()
39+
40+
self.setWindowTitle('SERVO CAM v{} | build {} | servocam.org'.format(self.tracker.version, self.tracker.build))
41+
42+
# create remote video capture thread
43+
self.video_thread = RemoteVideoThread(self)
44+
self.video_thread.handle_video_signal.connect(self.handle_video)
45+
self.video_thread.started_signal.connect(lambda: self.tracker.debug.log('[THREAD: VIDEO] Started'))
46+
self.video_thread.finished_signal.connect(lambda: self.tracker.debug.log('[THREAD: VIDEO] Exited'))
47+
self.video_thread.start()
48+
49+
# create socket connection thread
50+
self.socket_thread = SocketThread(self)
51+
self.socket_thread.handle_socket_signal.connect(self.handle_socket)
52+
self.socket_thread.started_signal.connect(lambda: self.tracker.debug.log('[THREAD: SOCKET] Started'))
53+
self.socket_thread.finished_signal.connect(lambda: self.tracker.debug.log('[THREAD: SOCKET] Exited'))
54+
self.socket_thread.start()
55+
56+
# create serial listen thread
57+
self.status_thread = StatusThread(self)
58+
self.status_thread.handle_status_signal.connect(self.handle_status)
59+
self.status_thread.started_signal.connect(lambda: self.tracker.debug.log('[THREAD: STATUS] Started'))
60+
self.status_thread.finished_signal.connect(lambda: self.tracker.debug.log('[THREAD: STATUS] Exited'))
61+
self.status_thread.start()
62+
63+
# show info about encryption
64+
if self.tracker.encrypt.enabled_data:
65+
self.tracker.debug.log("[AES ENCRYPTION] Data encryption is enabled")
66+
if self.tracker.encrypt.enabled_video:
67+
self.tracker.debug.log("[AES ENCRYPTION] Video stream encryption is enabled")
68+
69+
def setup(self):
70+
"""Setup app"""
71+
self.tracker.controller.init(self.tracker.source) # init tracker with default source
72+
self.timer = QTimer()
73+
self.timer.timeout.connect(self.update)
74+
self.timer.start(self.tracker.fps)
75+
76+
def update(self):
77+
"""On frame update"""
78+
self.tracker.update()
79+
80+
@Slot(np.ndarray)
81+
def handle_video(self, frame):
82+
"""
83+
Handle remote video thread signal
84+
85+
:param frame: video frame
86+
"""
87+
self.tracker.render.handle_thread(frame) # handle remote video
88+
89+
@Slot(str, str)
90+
def handle_socket(self, buff, ip):
91+
"""
92+
Handle socket thread signal
93+
94+
:param buff: received data
95+
:param ip: ip address
96+
"""
97+
self.tracker.sockets.handle_thread(buff, ip) # handle socket
98+
99+
@Slot(str)
100+
def handle_status(self, buff):
101+
"""
102+
Handle status thread signal
103+
104+
:param buff: received data
105+
"""
106+
self.tracker.status.handle_thread(buff) # handle status
107+
108+
def keyPressEvent(self, event):
109+
"""
110+
Handle key press event
111+
112+
:param event: key event
113+
"""
114+
super(MainWindow, self).keyPressEvent(event)
115+
self.tracker.keyboard.on_key_press(event)
116+
117+
def keyReleaseEvent(self, event):
118+
"""
119+
Handle key release event
120+
121+
:param event: key event
122+
"""
123+
super(MainWindow, self).keyReleaseEvent(event)
124+
self.tracker.keyboard.on_key_release(event)
125+
126+
# on close event
127+
def closeEvent(self, event):
128+
"""
129+
Handle close event
130+
131+
:param event: close event
132+
"""
133+
self.tracker.debug.log("Closing...")
134+
if self.video_thread is not None:
135+
self.tracker.debug.log("Waiting for video thread to exit...")
136+
self.video_thread.exiting = True
137+
138+
if self.socket_thread is not None:
139+
self.tracker.debug.log("Waiting for socket thread to exit...")
140+
self.socket_thread.exiting = True
141+
142+
if self.status_thread is not None:
143+
self.tracker.debug.log("Waiting for status thread to exit...")
144+
self.status_thread.exiting = True
145+
146+
self.tracker.debug.log("Exiting...")
147+
event.accept() # let the window close
148+
149+
150+
if __name__ == '__main__':
151+
app = QApplication(sys.argv)
152+
main_win = MainWindow()
153+
available_geometry = main_win.screen().availableGeometry()
154+
center = QScreen.availableGeometry(QApplication.primaryScreen()).center() / 2
155+
topLeftPoint = QScreen.availableGeometry(QApplication.primaryScreen()).topLeft()
156+
main_win.resize(available_geometry.width() / 2, available_geometry.height() / 2)
157+
main_win.show()
158+
main_win.move(topLeftPoint)
159+
160+
try:
161+
sys.exit(app.exec())
162+
except SystemExit:
163+
print("Closing...")

assets/__init__.py

Whitespace-only changes.

assets/defaults/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)