Make the lidar streamer ready to work with main controller

This commit is contained in:
Piv
2020-04-16 21:12:12 +09:30
parent 65c19e7494
commit ed371d3a2f
9 changed files with 53 additions and 23 deletions

View File

@@ -59,3 +59,6 @@ def getZmqPubSubStreamer(port):
def getTestingStreamer():
return TestStreamer()
# TODO: Create a general get method that will get the streamer based on an
# environment variable that is set.

View File

@@ -38,7 +38,7 @@ class CarServer():
return MotorServicer(self.vehicle)
def create_slam_servicer(self):
return SlamServicer('/dev/ttyUSB0')
return SlamServicer()
def create_lidar_servicer(self):
return LidarServicer()

View File

@@ -7,9 +7,9 @@ from multiprocessing import Process
class SlamServicer(grpc.SlamControlServicer):
slam_thread = None
def __init__(self, lidar_connection):
def __init__(self):
print('Servicer initialised')
self.slam = slam.SlamStreamer(lidar_connection=lidar_connection)
self.slam = slam.SlamStreamer()
def start_map_streaming(self, request, context):
print('Received Map Start Streaming Request')

View File

@@ -15,10 +15,9 @@ import tracking.devices.factory as lidar_fact
class SlamStreamer:
can_scan = False
def __init__(self, map_pixels=None, map_meters=None, lidar_connection=None, port=None):
def __init__(self, map_pixels=None, map_meters=None, port=None):
self._map_pixels = map_pixels
self._map_meters = map_meters
self._lidar_connection = lidar_connection
self._port = port
def start(self):
@@ -40,8 +39,8 @@ class SlamStreamer:
# Adapted from BreezySLAM rpslam example.
# Connect to Lidar unit. For some reason it likes to be done twice, otherwise it errors out...
lidar = lidar_fact.get_lidar(self._lidar_connection)
lidar = lidar_fact.get_lidar(self._lidar_connection)
lidar = lidar_fact.get_lidar()
lidar = lidar_fact.get_lidar()
print('Initialised lidar')

View File

@@ -186,7 +186,9 @@ def updateCarVelocity(oldGroup, newGroup):
tuple (DistanceChange, AngleChange)
A tuple containing how the groups' centres changed in the form (distance,angle)
"""
return (find_centre(newGroup))
old_polar = convert_cartesian_to_lidar(*find_centre(oldGroup))
new_centre = convert_cartesian_to_lidar(*find_centre(newGroup))
return (new_centre[0] - old_polar[0], new_centre[1] - old_polar[1])
def dualServoChange(newCentre, changeTuple):
@@ -197,7 +199,7 @@ def dualServoChange(newCentre, changeTuple):
Parameters
---------
newCentre
Tuple (distance,angle) of the new centre of the tracked group.
Tuple (distance, angle) of the new centre of the tracked group.
changeTuple
Tuple (distanceChange, angleChange) from the old centre to the new centre.

View File

View File

@@ -2,8 +2,11 @@ from tracking.devices.mock_lidar import MockLidar
from rplidar import RPLidar
import tracking.lidar_loader as loader
connection = "TEST"
# connection = '/dev/ttyUSB0'
def get_lidar(connection: str):
def get_lidar():
# Need a way to configure this, maybe with environment variables
if connection == 'TEST':
return MockLidar(loader.load_scans_bytes_file("tracking/out.pickle"))
else:

View File

@@ -19,12 +19,13 @@ class LidarCache():
self.run = True
self.tracking_group_number = -1
self.currentGroups = None
self._group_listeners = []
def start_cache(self, sender):
self.thread = Thread(target=self.do_scanning, args=[sender])
def start_cache(self):
self.thread = Thread(target=self.do_scanning)
self.thread.start()
def do_scanning(self, listener):
def do_scanning(self):
"""Performs scans whilst cache is running, and will pass calculated groups data to the sender.
Parameters
@@ -33,8 +34,6 @@ class LidarCache():
Any object that includes the onGroupsChanged method.
"""
# Create the 0MQ socket first. This should not be passed between threads.
self._mFactory = listener
# Batch over scans, so we don't need to do our own batching to determine groups
# TODO: Implement custom batching, as iter_scans can be unreliable
@@ -65,7 +64,21 @@ class LidarCache():
pointScan.points.append(tracker_pb.Point(
angle=point[1], distance=point[2], group_number=group.number))
self._mFactory.onGroupsChanged(pointScan)
for listener in self._group_listeners:
listener.onGroupsChanged(pointScan)
def add_groups_changed_listener(self, listener):
"""
Add a listener for a change in scans. THis will provide a tuple with the new group
scans, which can then be sent off to a network listener for display, or to update the
vehicle with a new velocity.
Parameters
----------
listener
An object that implements the onGroupsChanged(message) method.
"""
self._group_listeners.append(listener)
def stop_scanning(self):
self.run = False

View File

@@ -3,21 +3,25 @@ from tracking.lidar_tracker_pb2_grpc import PersonTrackingServicer
from tracking.lidar_cache import LidarCache
from multiprocessing import Process
import messaging.message_factory as mf
from rplidar import RPLidar
from messaging import messages
import tracking.devices.factory as lidar_factory
from messaging import messages
import tracking.algorithms as alg
class LidarServicer(PersonTrackingServicer):
def __init__(self):
def __init__(self, vehicle=None):
# TODO: Put the rplidar creation in a factory or something, to make it possible to test this servicer.
# Also, it would allow creating the service without the lidar being connected.
self.cache = LidarCache(RPLidar('/dev/ttyUSB0'), measurements=100)
self.cache = LidarCache(lidar_factory.get_lidar(), measurements=100)
self.cache.add_groups_changed_listener(self)
self._mFactory = None
self._port = None
self._vehicle = vehicle
self._tracked_group = None
def set_tracking_group(self, request, context):
pass
self._tracked_group = request.value
def stop_tracking(self, request, context):
self.cache.stop_scanning()
@@ -25,10 +29,16 @@ class LidarServicer(PersonTrackingServicer):
def start_tracking(self, request, context):
"""Starts the lidar cache, streaming on the provided port."""
self._port = request.value
self.cache.start_cache(self)
self.cache.start_cache()
def onGroupsChanged(self, message):
if self._mFactory is None:
# Create the zmq socket in the thread that it will be used, just to be safe.
self._mFactory = mf.getZmqPubSubStreamer(self._port)
self._mFactory.send_message_topic("lidar_map", messages.ProtoMessage(message=message.SerializeToString()))
if self._tracked_group is not None and self._vehicle is not None:
# Update vehicle to correctly follow the tracked group.
# Leave for now, need to work out exactly how this will change.
# alg.dualServoChange(alg.find_centre())
pass