Refactor python module structure
This commit is contained in:
83
control/MotorServer.py
Executable file
83
control/MotorServer.py
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from threading import Timer, Thread
|
||||
from gpiozero import Servo, Device
|
||||
from concurrent import futures
|
||||
import time
|
||||
|
||||
import grpc
|
||||
|
||||
import control.motorService_pb2 as motorService_pb2
|
||||
import control.motorService_pb2_grpc as motorService_pb2_grpc
|
||||
from control.gpiozero.motor_session import Motor
|
||||
from slam.slam_servicer import SlamServicer
|
||||
import slam.SlamController_pb2_grpc as SlamController_pb2_grpc
|
||||
|
||||
|
||||
class MotorServicer(motorService_pb2_grpc.CarControlServicer):
|
||||
def __init__(self, motor, servo):
|
||||
self.motor = motor
|
||||
self.servo = servo
|
||||
self._timer = None
|
||||
|
||||
def SetThrottle(self, request, context):
|
||||
# gRPC streams currently don't work between python and android.
|
||||
# If we don't get a response every 3 seconds, stop the car.
|
||||
throttleFailed = False
|
||||
print('Setting throttle to: ' + str(request.throttle))
|
||||
self.set_timeout(3)
|
||||
throttleFailed = self.motor.set_throttle(request.throttle)
|
||||
return motorService_pb2.ThrottleResponse(throttleSet=throttleFailed)
|
||||
|
||||
def SetSteering(self, request, context):
|
||||
# TODO: Fix this to use the motor object as well to check for bounds.
|
||||
print('Setting steering to: ' + str(request.steering))
|
||||
self.servo.value = request.steering
|
||||
return motorService_pb2.SteeringResponse(steeringSet=True)
|
||||
|
||||
def set_timeout(self, min_timeout):
|
||||
"""Stops the old timer and restarts it to the specified time.
|
||||
|
||||
min_timeout -- The minimum time that can be used for the timer.
|
||||
"""
|
||||
if self._timer is not None:
|
||||
self._timer.cancel()
|
||||
self._timer = Timer(min_timeout, self.timeout_elapsed)
|
||||
self._timer.start()
|
||||
|
||||
def timeout_elapsed(self):
|
||||
"""Election or heartbeat timeout has elapsed."""
|
||||
print("Node timeout elapsed")
|
||||
self.motor.stop()
|
||||
|
||||
def start_server(self):
|
||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=8))
|
||||
motorService_pb2_grpc.add_CarControlServicer_to_server(self, server)
|
||||
SlamController_pb2_grpc.add_SlamControlServicer_to_server(
|
||||
self.create_slam_servicer(), server)
|
||||
# Disable tls for local testing.
|
||||
# server.add_secure_port('[::]:50051', self.create_credentials())
|
||||
server.add_insecure_port('[::]:50051')
|
||||
server.start()
|
||||
while True:
|
||||
time.sleep(60*60)
|
||||
|
||||
def create_slam_servicer(self):
|
||||
return SlamServicer('/dev/ttyUSB0')
|
||||
|
||||
def create_credentials(self):
|
||||
pvtKeyPath = '/home/pi/tls/device.key'
|
||||
pvtCertPath = '/home/pi/tls/device.crt'
|
||||
|
||||
pvtKeyBytes = open(pvtKeyPath, 'rb').read()
|
||||
pvtCertBytes = open(pvtCertPath, 'rb').read()
|
||||
|
||||
return grpc.ssl_server_credentials([[pvtKeyBytes, pvtCertBytes]])
|
||||
|
||||
|
||||
motor = Motor()
|
||||
servo = Servo(18)
|
||||
servicer = MotorServicer(motor, servo)
|
||||
|
||||
service_thread = Thread(target=servicer.start_server)
|
||||
service_thread.start()
|
||||
33
control/PythonRemoteController.py
Normal file
33
control/PythonRemoteController.py
Normal file
@@ -0,0 +1,33 @@
|
||||
print("Connecting to pi")
|
||||
|
||||
import grpc
|
||||
from concurrent import futures
|
||||
import motorService_pb2_grpc
|
||||
from motorService_pb2 import SteeringRequest, ThrottleRequest
|
||||
import time
|
||||
|
||||
throttle = 0.1
|
||||
timer = None
|
||||
|
||||
class ThrottleIterator:
|
||||
'''
|
||||
Class to get the current throttle for the car.
|
||||
Will return a random throttle between
|
||||
'''
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if throttle > 1 or throttle < -1:
|
||||
raise StopIteration
|
||||
time.sleep(1)
|
||||
return ThrottleRequest(throttle=throttle)
|
||||
|
||||
|
||||
channel = grpc.insecure_channel('10.0.0.53:50051')
|
||||
stub = motorService_pb2_grpc.CarControlStub(channel)
|
||||
|
||||
response = stub.SetThrottle(ThrottleIterator())
|
||||
|
||||
while True:
|
||||
throttle = int(input('Please enter a value for the throttle between -100 and 100'))
|
||||
0
control/__init__.py
Normal file
0
control/__init__.py
Normal file
0
control/gpiozero/__init__.py
Normal file
0
control/gpiozero/__init__.py
Normal file
43
control/gpiozero/motor_session.py
Normal file
43
control/gpiozero/motor_session.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from gpiozero import Servo, Device
|
||||
from gpiozero.pins.pigpio import PiGPIOFactory
|
||||
import subprocess
|
||||
|
||||
class Motor:
|
||||
def __init__(self, motor_pin=19):
|
||||
subprocess.call(['sudo', 'pigpiod'])
|
||||
Device.pin_factory = PiGPIOFactory()
|
||||
print('Using pin factory:')
|
||||
print(Device.pin_factory)
|
||||
self.set_motor_pin(motor_pin)
|
||||
self.initialise_motor()
|
||||
|
||||
def initialise_motor(self):
|
||||
if self._motor_pin is None:
|
||||
print("Motor pin number is not set.")
|
||||
return
|
||||
self._servo = Servo(self._motor_pin, pin_factory=Device.pin_factory)
|
||||
|
||||
def set_throttle(self, throttle):
|
||||
try:
|
||||
if throttle < -1 or throttle > 1:
|
||||
print("Not setting throttle, invalid value set.")
|
||||
return False
|
||||
self._servo.value = throttle
|
||||
except TypeError:
|
||||
print("throttle should be a number, preferably a float.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def set_motor_pin(self, value):
|
||||
if isinstance(value, int):
|
||||
if value < 2 or value > 21:
|
||||
print("Invalid GPIO pin")
|
||||
return False
|
||||
self._motor_pin = value
|
||||
return True
|
||||
else:
|
||||
print("Value must be an int.")
|
||||
return False
|
||||
|
||||
def stop(self):
|
||||
self.set_throttle(0)
|
||||
220
control/motorService_pb2.py
Normal file
220
control/motorService_pb2.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: motorService.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='motorService.proto',
|
||||
package='MotorControl',
|
||||
syntax='proto3',
|
||||
serialized_options=None,
|
||||
serialized_pb=_b('\n\x12motorService.proto\x12\x0cMotorControl\"#\n\x0fThrottleRequest\x12\x10\n\x08throttle\x18\x01 \x01(\x02\"\'\n\x10ThrottleResponse\x12\x13\n\x0bthrottleSet\x18\x01 \x01(\x08\"#\n\x0fSteeringRequest\x12\x10\n\x08steering\x18\x01 \x01(\x02\"\'\n\x10SteeringResponse\x12\x13\n\x0bsteeringSet\x18\x01 \x01(\x08\x32\xac\x01\n\nCarControl\x12N\n\x0bSetThrottle\x12\x1d.MotorControl.ThrottleRequest\x1a\x1e.MotorControl.ThrottleResponse\"\x00\x12N\n\x0bSetSteering\x12\x1d.MotorControl.SteeringRequest\x1a\x1e.MotorControl.SteeringResponse\"\x00\x62\x06proto3')
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
_THROTTLEREQUEST = _descriptor.Descriptor(
|
||||
name='ThrottleRequest',
|
||||
full_name='MotorControl.ThrottleRequest',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='throttle', full_name='MotorControl.ThrottleRequest.throttle', index=0,
|
||||
number=1, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=float(0),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=36,
|
||||
serialized_end=71,
|
||||
)
|
||||
|
||||
|
||||
_THROTTLERESPONSE = _descriptor.Descriptor(
|
||||
name='ThrottleResponse',
|
||||
full_name='MotorControl.ThrottleResponse',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='throttleSet', full_name='MotorControl.ThrottleResponse.throttleSet', index=0,
|
||||
number=1, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=73,
|
||||
serialized_end=112,
|
||||
)
|
||||
|
||||
|
||||
_STEERINGREQUEST = _descriptor.Descriptor(
|
||||
name='SteeringRequest',
|
||||
full_name='MotorControl.SteeringRequest',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='steering', full_name='MotorControl.SteeringRequest.steering', index=0,
|
||||
number=1, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=float(0),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=114,
|
||||
serialized_end=149,
|
||||
)
|
||||
|
||||
|
||||
_STEERINGRESPONSE = _descriptor.Descriptor(
|
||||
name='SteeringResponse',
|
||||
full_name='MotorControl.SteeringResponse',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='steeringSet', full_name='MotorControl.SteeringResponse.steeringSet', index=0,
|
||||
number=1, type=8, cpp_type=7, label=1,
|
||||
has_default_value=False, default_value=False,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=151,
|
||||
serialized_end=190,
|
||||
)
|
||||
|
||||
DESCRIPTOR.message_types_by_name['ThrottleRequest'] = _THROTTLEREQUEST
|
||||
DESCRIPTOR.message_types_by_name['ThrottleResponse'] = _THROTTLERESPONSE
|
||||
DESCRIPTOR.message_types_by_name['SteeringRequest'] = _STEERINGREQUEST
|
||||
DESCRIPTOR.message_types_by_name['SteeringResponse'] = _STEERINGRESPONSE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
ThrottleRequest = _reflection.GeneratedProtocolMessageType('ThrottleRequest', (_message.Message,), {
|
||||
'DESCRIPTOR' : _THROTTLEREQUEST,
|
||||
'__module__' : 'motorService_pb2'
|
||||
# @@protoc_insertion_point(class_scope:MotorControl.ThrottleRequest)
|
||||
})
|
||||
_sym_db.RegisterMessage(ThrottleRequest)
|
||||
|
||||
ThrottleResponse = _reflection.GeneratedProtocolMessageType('ThrottleResponse', (_message.Message,), {
|
||||
'DESCRIPTOR' : _THROTTLERESPONSE,
|
||||
'__module__' : 'motorService_pb2'
|
||||
# @@protoc_insertion_point(class_scope:MotorControl.ThrottleResponse)
|
||||
})
|
||||
_sym_db.RegisterMessage(ThrottleResponse)
|
||||
|
||||
SteeringRequest = _reflection.GeneratedProtocolMessageType('SteeringRequest', (_message.Message,), {
|
||||
'DESCRIPTOR' : _STEERINGREQUEST,
|
||||
'__module__' : 'motorService_pb2'
|
||||
# @@protoc_insertion_point(class_scope:MotorControl.SteeringRequest)
|
||||
})
|
||||
_sym_db.RegisterMessage(SteeringRequest)
|
||||
|
||||
SteeringResponse = _reflection.GeneratedProtocolMessageType('SteeringResponse', (_message.Message,), {
|
||||
'DESCRIPTOR' : _STEERINGRESPONSE,
|
||||
'__module__' : 'motorService_pb2'
|
||||
# @@protoc_insertion_point(class_scope:MotorControl.SteeringResponse)
|
||||
})
|
||||
_sym_db.RegisterMessage(SteeringResponse)
|
||||
|
||||
|
||||
|
||||
_CARCONTROL = _descriptor.ServiceDescriptor(
|
||||
name='CarControl',
|
||||
full_name='MotorControl.CarControl',
|
||||
file=DESCRIPTOR,
|
||||
index=0,
|
||||
serialized_options=None,
|
||||
serialized_start=193,
|
||||
serialized_end=365,
|
||||
methods=[
|
||||
_descriptor.MethodDescriptor(
|
||||
name='SetThrottle',
|
||||
full_name='MotorControl.CarControl.SetThrottle',
|
||||
index=0,
|
||||
containing_service=None,
|
||||
input_type=_THROTTLEREQUEST,
|
||||
output_type=_THROTTLERESPONSE,
|
||||
serialized_options=None,
|
||||
),
|
||||
_descriptor.MethodDescriptor(
|
||||
name='SetSteering',
|
||||
full_name='MotorControl.CarControl.SetSteering',
|
||||
index=1,
|
||||
containing_service=None,
|
||||
input_type=_STEERINGREQUEST,
|
||||
output_type=_STEERINGRESPONSE,
|
||||
serialized_options=None,
|
||||
),
|
||||
])
|
||||
_sym_db.RegisterServiceDescriptor(_CARCONTROL)
|
||||
|
||||
DESCRIPTOR.services_by_name['CarControl'] = _CARCONTROL
|
||||
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
63
control/motorService_pb2_grpc.py
Normal file
63
control/motorService_pb2_grpc.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
||||
import grpc
|
||||
|
||||
import control.motorService_pb2 as motorService__pb2
|
||||
|
||||
|
||||
class CarControlStub(object):
|
||||
# missing associated documentation comment in .proto file
|
||||
pass
|
||||
|
||||
def __init__(self, channel):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
channel: A grpc.Channel.
|
||||
"""
|
||||
self.SetThrottle = channel.unary_unary(
|
||||
'/MotorControl.CarControl/SetThrottle',
|
||||
request_serializer=motorService__pb2.ThrottleRequest.SerializeToString,
|
||||
response_deserializer=motorService__pb2.ThrottleResponse.FromString,
|
||||
)
|
||||
self.SetSteering = channel.unary_unary(
|
||||
'/MotorControl.CarControl/SetSteering',
|
||||
request_serializer=motorService__pb2.SteeringRequest.SerializeToString,
|
||||
response_deserializer=motorService__pb2.SteeringResponse.FromString,
|
||||
)
|
||||
|
||||
|
||||
class CarControlServicer(object):
|
||||
# missing associated documentation comment in .proto file
|
||||
pass
|
||||
|
||||
def SetThrottle(self, request, context):
|
||||
# missing associated documentation comment in .proto file
|
||||
pass
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def SetSteering(self, request, context):
|
||||
# missing associated documentation comment in .proto file
|
||||
pass
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
|
||||
def add_CarControlServicer_to_server(servicer, server):
|
||||
rpc_method_handlers = {
|
||||
'SetThrottle': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.SetThrottle,
|
||||
request_deserializer=motorService__pb2.ThrottleRequest.FromString,
|
||||
response_serializer=motorService__pb2.ThrottleResponse.SerializeToString,
|
||||
),
|
||||
'SetSteering': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.SetSteering,
|
||||
request_deserializer=motorService__pb2.SteeringRequest.FromString,
|
||||
response_serializer=motorService__pb2.SteeringResponse.SerializeToString,
|
||||
),
|
||||
}
|
||||
generic_handler = grpc.method_handlers_generic_handler(
|
||||
'MotorControl.CarControl', rpc_method_handlers)
|
||||
server.add_generic_rpc_handlers((generic_handler,))
|
||||
Reference in New Issue
Block a user