python vtk 3d激光雷达点云查看器延迟

时间:2019-06-19 02:50:22

标签: python timer vtk

“嗨,我是初学者。 我想使用vtk库查看传感器点云。 所以我做了。 首先,我在计时器回调函数中接收原始传感器数据。 但它有延迟时间,大约2秒。 所以我使用多处理管道。 我在父进程中收到原始传感器数据。 子进程显示了这一点。 但它仍然有延迟时间。 我认为这是由于计时器回调。 因为仅接收传感器数据没有延迟。 如果我在计时器回调函数中收到传感器数据,则有延迟。 我不知道其他方式 您能给我一些有关延误或其他方式的建议吗? 谢谢。”

我尝试了多处理。 父过程:接收原始传感器数据并转换x,y,z位置 子过程:显示点云

import socket
import numpy as np
from multiprocessing import Process, Queue, Pipe
import struct
from numpy import random
import vtk

HOST = "192.168.1.201"
PORT = 2368

LASER_ANGLES = [-15, 1, -13, 3, -11, 5, -9, 7, -7, 9, -5, 11, -3, 13, -1, 15]
NUM_LASERS = 16

EXPECTED_PACKET_TIME = 0.001327  # valid only in "the strongest return mode"
EXPECTED_SCAN_DURATION = 0.1
DISTANCE_RESOLUTION = 0.002
ROTATION_RESOLUTION = 0.01
ROTATION_MAX_UNITS = 36000

soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
soc.bind(('', PORT))

x_thresh = [-1.1, 2.1]
y_thresh = [1.5, 4.5]
z_thresh = [-0.4, 2.1]

class VtkPointCloud:
    def __init__(self, zMin=-1.0, zMax=1.0, maxNumPoints=1e6):
        global count
        self.maxNumPoints = maxNumPoints
        self.vtkPolyData = vtk.vtkPolyData()
        self.clearPoints()
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputData(self.vtkPolyData)
        mapper.SetColorModeToDefault()
        mapper.SetScalarRange(zMin, zMax)
        mapper.SetScalarVisibility(1)
        self.vtkActor = vtk.vtkActor()
        self.vtkActor.SetMapper(mapper)


    def addPoint(self, point, color_num):
        if self.vtkPoints.GetNumberOfPoints() < self.maxNumPoints:
            pointId = self.vtkPoints.InsertNextPoint(point[:])
            self.vtkDepth.InsertNextValue(color_num)
            self.vtkCells.InsertNextCell(1)
            self.vtkCells.InsertCellPoint(pointId)
        else:
            r = random.randint(0, self.maxNumPoints)
            self.vtkPoints.SetPoint(r, point[:])
        self.vtkCells.Modified()
        self.vtkPoints.Modified()
        self.vtkDepth.Modified()

    def clearPoints(self):
        self.vtkPoints = vtk.vtkPoints()
        self.vtkCells = vtk.vtkCellArray()
        self.vtkDepth = vtk.vtkDoubleArray()
        self.vtkDepth.SetName('DepthArray')
        self.vtkPolyData.SetPoints(self.vtkPoints)
        self.vtkPolyData.SetVerts(self.vtkCells)
        self.vtkPolyData.GetPointData().SetScalars(self.vtkDepth)
        self.vtkPolyData.GetPointData().SetActiveScalars('DepthArray')

    def addPlane(self, plane_center, normal, x_axis, y_axis):
        self.vtkPlanes.SetCenter(plane_center)
        self.vtkPlanes.SetNormal(normal)
        self.vtkPlanes.SetPoint1(x_axis)
        self.vtkPlanes.SetPoint2(y_axis)

class AddPointCloudTimerCallback():
    def __init__(self, renderer):
        self.renderer = renderer
        self.prev_azimuth = 0

    def execute(self, iren, event):
        self.renderer.RemoveAllViewProps()
        pointCloud = VtkPointCloud()
        self.renderer.AddActor(pointCloud.vtkActor)
        data = child_conn.recv()
        for point in data:
            if (point[0] > x_thresh[0]) and (point[0] < x_thresh[1]) and \
               (point[1] > y_thresh[0]) and (point[1] < y_thresh[1]) and \
               (point[2] > z_thresh[0]) and (point[2] < z_thresh[1]):
                color_num = 0.7
            else:
                color_num = -1
            pointCloud.addPoint(point, color_num)

        iren.GetRenderWindow().Render()
        #self.renderer.ResetCamera()

def get_data():
    # Renderer
    renderer = vtk.vtkRenderer()
    renderer.SetBackground(0.0, 0.0, 0.0)
    renderer.ResetCamera()

    # Render Window
    renderWindow = vtk.vtkRenderWindow()
    renderWindow.AddRenderer(renderer)
    renderWindow.SetSize(1024, 1024)

    # Interactor
    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)
    renderWindowInteractor.Initialize()

    # Initialize a timer for the animation
    addPointCloudTimerCallback = AddPointCloudTimerCallback(renderer)
    renderWindowInteractor.AddObserver('TimerEvent', addPointCloudTimerCallback.execute)
    timerId = renderWindowInteractor.CreateRepeatingTimer(0)
    addPointCloudTimerCallback.timerId = timerId

    # Begin Interaction
    axes = vtk.vtkAxesActor()
    widget = vtk.vtkOrientationMarkerWidget()
    widget.SetOutlineColor(0.9300, 0.5700, 0.1300)
    widget.SetOrientationMarker(axes)
    widget.SetInteractor(renderWindowInteractor)
    widget.SetViewport(0.0, 0.0, 0.4, 0.4)
    widget.SetEnabled(1)
    widget.InteractiveOn()
    renderWindow.Render()
    renderWindowInteractor.Start()

def calc(dis, azimuth, laser_id):

    R = dis * DISTANCE_RESOLUTION
    omega = LASER_ANGLES[laser_id] * np.pi / 180.0
    alpha = azimuth / 100.0 * np.pi / 180.0
    X = R * np.cos(omega) * np.sin(alpha)
    Y = R * np.cos(omega) * np.cos(alpha)
    Z = R * np.sin(omega)
    return [X, Y, Z]

def load_data():
    while True:
        points = []
        data, addr = soc.recvfrom(2000)
        seq_index = 0
        for offset in range(0, 1200, 100):
            flag, azimuth = struct.unpack_from("<HH", data, offset)
            for step in range(2):
                seq_index += 1
                azimuth += step
                azimuth %= ROTATION_MAX_UNITS
                arr = struct.unpack_from('<' + "HB" * 16, data, offset + 4 + step * 48)

                for i in range(NUM_LASERS):
                    if arr[i*2] > 0:
                        time_offset = (55.296 * seq_index + 2.304 * i) / 1000000.0
                        point = calc(arr[i * 2], azimuth, i)
                        points.append(point)
        parent_conn.send(points)

if __name__ == "__main__":
    parent_conn, child_conn = Pipe()
    processA = Process(target = load_data, args = ()).start()
    processB = Process(target = get_data, args = ()).start()

我想解决计时器回调延迟。想要其他有关实时传感器查看器的方法。

0 个答案:

没有答案