“嗨,我是初学者。 我想使用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()
我想解决计时器回调延迟。想要其他有关实时传感器查看器的方法。