0

I am using a precoded script since I am a Python noob and run into some trouble concerning socket programming.

I use two computers, one is running a Matlab/Simulink real time application, which is sending data via UDP to my windows laptop. The data contains the XY-coordinates for the cursor and a target, target radius and color (6 signals in total). On the laptop, I am running a python script, which ideally would read out the udp signal and draw ellipses on a secondary screen at given coordinates in real-time (or close to real time). Unfortunately, the execution is maybe not fast enough to keep up with the UDP signal, which is being sent at 1000Hz. This results in a hefty delay of about 40 seconds between a change in the sent signal to display on the screen.

If I am correct, the issue is in the recvfrom command. Data received is being stored in some sort of buffer and is displayed in FIFO style, instead of displaying everything real time at 1000Hz. The problem is that I do not know how to fix this. Most explanations about socket programming are way over my head. It doesnt need to be displayed at 1000Hz, 50Hz would be fine, but it would just be very nice to display changes asap. Rather than FIFO, I would like to read only the last received data.

Can anyone help me out? Thank you in advance.

import socket
import struct
from PySide import QtGui
from PySide import QtCore
import random
import ctypes
import sys
import time
import math

UDP_IP = "192.168.1.25" #server
UDP_PORT = 25000 #server

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT)) #


class MyGui(QtGui.QWidget):

    def __init__(self):

        super(MyGui,self).__init__()

        #self.screen()
        user32 = ctypes.windll.user32
        self._W = user32.GetSystemMetrics(0)
        self._H = user32.GetSystemMetrics(1)
        self._rW = random.random()
        self._rH = random.random()
        self._rR = random.random()
        self._rC = 500

        self._CursorX = 0
        self._CursorY = 0
        self._CursorXt = 0
        self._CursorYt = 0
        self._CursorRt = 0
        self._Color = 0    

        print(self.geometry())
        self._W = self.width()
        self.setStyleSheet("background-color: black")
        self.setGeometry(QtCore.QRect(2000,50,500,300))
        self.showFullScreen()


    def paintEvent(self, e):
        qp = QtGui.QPainter()
        qp.begin(self)
        self._drawTarget(qp)
        self._drawCursor(qp)
        qp.end()

    def _drawTarget(self, qpT):

        # color1 = QtGui.QColor()
        # color1.setNamedColor('#d4d4d4')

        color1=QtGui.QColor(self._Color)

        qpT.setPen(color1)

        qpT.setBrush(QtGui.QColor(self._Color))
        qpT.drawEllipse(QtCore.QPointF(self._CursorXt, self._CursorYt), self._CursorRt, self._CursorRt)

    def _drawCursor(self, qpC):

        color2 = QtGui.QColor(0, 0, 0)
        color2.setNamedColor('#FFFF00')
        qpC.setPen(color2)

        qpC.setBrush(QtGui.QColor('#FFFF00'))
        qpC.drawEllipse(QtCore.QPointF(self._CursorX, self._CursorY), 20, 20)

    def mousePressEvent(self, QMouseEvent):
        print ("mouse position")
        print (QMouseEvent.pos())

    def setCursorPosition(self,x,y,xt,yt,Rt,color):
        self._CursorX = x
        self._CursorY = y
        self._CursorXt = xt
        self._CursorYt = yt
        self._CursorRt = Rt
        self._Color = color 
        self.update()



class MyProcess:
    def __init__(self, whichGui):
        self._x = 0
        self._y = 0 
        self._xt = 0
        self._yt = 0
        self._Rt = 0
        self._color = 0
        self._whichGui = whichGui
        self._T = QtCore.QTimer()
        self._T.timeout.connect(self._update)
        self._T.start(30)

    def _update(self):

        data, addr = sock.recvfrom(8*6)
        #print ("received message:", data)
        value = struct.unpack('dddddd', data)
        #print (value)
        self._xt = value[0]
        self._yt = value[1]
        self._Rt = value[2]
        self._x = value[3]
        self._y = value[4]
        self._color = value[5]
        self._whichGui.setCursorPosition(self._x, self._y, self._xt, self._yt, self._Rt, self._color)


# Run the Graph
G = MyGui()
G.show()


P = MyProcess(G)
Gilian
  • 1
  • 1
    On what grounds do you say that `recvfrom` is the problem? Have you created a minimal test case where it just times receiving the data and (perhaps) displays the raw numbers as text in the commandline? That is the sort of minimal example people would need to be able to help you, since I doubt people are going to hunt through your GUI code to find the actually relevant part. – TheBlackCat Nov 28 '16 at 17:30
  • There are several reasons it could be too slow. You'll need to do some tests to determine the reason. Are you certain it isn't the sender that is too slow? – willpower2727 Nov 28 '16 at 18:10
  • Thank you for your replies! I will try and do some test such as printing raw numbers asap. Furthermore, I base my suggestion of the recvfrom might be the problem on the follow test that I did: I was running a simluation and only putting out constant numbers. I changed the value of the constant and immediately took out the UDP cable between the two computers. Still, after about 40 seconds, the change in value of the constant was displayed. This must mean that the sender had sent the values before and it was stored somewhere in a buffer on the second pc. – Gilian Nov 29 '16 at 09:29

0 Answers0