From eee4e6d4de58e7ce92ec6407756afa4c8c8cc772 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Sun, 11 Aug 2019 20:31:16 +0930 Subject: [PATCH] Add motor control with grpc --- MotorControl/MotorServer.py | 11 + MotorControl/gpiozero/motor_session.py | 40 ++++ MotorControl/motor.py | 16 +- MotorControl/motorService_pb2.py | 307 +++++++++++++++++++++++++ MotorControl/motorService_pb2_grpc.py | 80 +++++++ MotorControl/protos/motorService.proto | 33 +++ 6 files changed, 473 insertions(+), 14 deletions(-) create mode 100644 MotorControl/MotorServer.py create mode 100644 MotorControl/gpiozero/motor_session.py create mode 100644 MotorControl/motorService_pb2.py create mode 100644 MotorControl/motorService_pb2_grpc.py create mode 100644 MotorControl/protos/motorService.proto diff --git a/MotorControl/MotorServer.py b/MotorControl/MotorServer.py new file mode 100644 index 0000000..99d22c4 --- /dev/null +++ b/MotorControl/MotorServer.py @@ -0,0 +1,11 @@ +import MotorControl.motorService_pb2 as motorService_pb2 +import MotorControl.motorService_pb2_grpc as motorService_pb2_grpc + +from MotorControl.gpiozero.motor_session import Motor + +class MotorServer(motorService_pb2_grpc.CarControlServicer): + def __init__(self): + self.motor = Motor() + + def ThrottleRequestRPC(self, request, context): + \ No newline at end of file diff --git a/MotorControl/gpiozero/motor_session.py b/MotorControl/gpiozero/motor_session.py new file mode 100644 index 0000000..aa30e96 --- /dev/null +++ b/MotorControl/gpiozero/motor_session.py @@ -0,0 +1,40 @@ +import os +from gpiozero import Servo + +GPIOZERO_PIN_FACTORY = "piggpio" + +class Motor: + def __init__(self, motor_pin=19): + os.environ["GPIOZERO_PIN_FACTORY"] = GPIOZERO_PIN_FACTORY + os.system("sudo pigpiod") + 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) + + 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 + diff --git a/MotorControl/motor.py b/MotorControl/motor.py index 95a0352..23664d8 100644 --- a/MotorControl/motor.py +++ b/MotorControl/motor.py @@ -1,8 +1,6 @@ import time from abc import ABC, abstractmethod -from RPi import GPIO - import MotorControl.servo as servo """This module controls the Motor and Servo control. @@ -20,18 +18,8 @@ class Motor(servo.Servo, ABC): class MotorController(Motor): - def __init__(self, pin_number, frequency, duty_cycle=0): - self._duty_cycle = duty_cycle - self._operating_frequency = frequency - self._running = False - self.pin_number = pin_number - - # Operating Frequency should be 50Hz - - GPIO.setmode(GPIO.BCM) - GPIO.setup(self.pin_number, self._operating_frequency) - self._control_pin = GPIO.PWM(self.pin_number, self._duty_cycle) - + def __init__(self, pin_number, frequency): + @property def duty_cycle(self): diff --git a/MotorControl/motorService_pb2.py b/MotorControl/motorService_pb2.py new file mode 100644 index 0000000..0509271 --- /dev/null +++ b/MotorControl/motorService_pb2.py @@ -0,0 +1,307 @@ +# -*- 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\"\"\n\x0eHeartbeatCheck\x12\x10\n\x08\x63ontinue\x18\x01 \x01(\x08\".\n\x16HeartbeatCheckResponse\x12\x14\n\x0c\x65rrorMessage\x18\x01 \x01(\t2\x81\x02\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\x12S\n\tHeartbeat\x12\x1c.MotorControl.HeartbeatCheck\x1a$.MotorControl.HeartbeatCheckResponse\"\x00(\x01\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, +) + + +_HEARTBEATCHECK = _descriptor.Descriptor( + name='HeartbeatCheck', + full_name='MotorControl.HeartbeatCheck', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='continue', full_name='MotorControl.HeartbeatCheck.continue', 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=192, + serialized_end=226, +) + + +_HEARTBEATCHECKRESPONSE = _descriptor.Descriptor( + name='HeartbeatCheckResponse', + full_name='MotorControl.HeartbeatCheckResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='errorMessage', full_name='MotorControl.HeartbeatCheckResponse.errorMessage', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + 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=228, + serialized_end=274, +) + +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 +DESCRIPTOR.message_types_by_name['HeartbeatCheck'] = _HEARTBEATCHECK +DESCRIPTOR.message_types_by_name['HeartbeatCheckResponse'] = _HEARTBEATCHECKRESPONSE +_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) + +HeartbeatCheck = _reflection.GeneratedProtocolMessageType('HeartbeatCheck', (_message.Message,), { + 'DESCRIPTOR' : _HEARTBEATCHECK, + '__module__' : 'motorService_pb2' + # @@protoc_insertion_point(class_scope:MotorControl.HeartbeatCheck) + }) +_sym_db.RegisterMessage(HeartbeatCheck) + +HeartbeatCheckResponse = _reflection.GeneratedProtocolMessageType('HeartbeatCheckResponse', (_message.Message,), { + 'DESCRIPTOR' : _HEARTBEATCHECKRESPONSE, + '__module__' : 'motorService_pb2' + # @@protoc_insertion_point(class_scope:MotorControl.HeartbeatCheckResponse) + }) +_sym_db.RegisterMessage(HeartbeatCheckResponse) + + + +_CARCONTROL = _descriptor.ServiceDescriptor( + name='CarControl', + full_name='MotorControl.CarControl', + file=DESCRIPTOR, + index=0, + serialized_options=None, + serialized_start=277, + serialized_end=534, + 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, + ), + _descriptor.MethodDescriptor( + name='Heartbeat', + full_name='MotorControl.CarControl.Heartbeat', + index=2, + containing_service=None, + input_type=_HEARTBEATCHECK, + output_type=_HEARTBEATCHECKRESPONSE, + serialized_options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_CARCONTROL) + +DESCRIPTOR.services_by_name['CarControl'] = _CARCONTROL + +# @@protoc_insertion_point(module_scope) diff --git a/MotorControl/motorService_pb2_grpc.py b/MotorControl/motorService_pb2_grpc.py new file mode 100644 index 0000000..b6d624a --- /dev/null +++ b/MotorControl/motorService_pb2_grpc.py @@ -0,0 +1,80 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import 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, + ) + self.Heartbeat = channel.stream_unary( + '/MotorControl.CarControl/Heartbeat', + request_serializer=motorService__pb2.HeartbeatCheck.SerializeToString, + response_deserializer=motorService__pb2.HeartbeatCheckResponse.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 Heartbeat(self, request_iterator, 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, + ), + 'Heartbeat': grpc.stream_unary_rpc_method_handler( + servicer.Heartbeat, + request_deserializer=motorService__pb2.HeartbeatCheck.FromString, + response_serializer=motorService__pb2.HeartbeatCheckResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'MotorControl.CarControl', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/MotorControl/protos/motorService.proto b/MotorControl/protos/motorService.proto new file mode 100644 index 0000000..1b5ce9e --- /dev/null +++ b/MotorControl/protos/motorService.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; + +package MotorControl; + +message ThrottleRequest{ + float throttle = 1; +} + +message ThrottleResponse{ + bool throttleSet = 1; +} + +message SteeringRequest{ + float steering = 1; +} + +message SteeringResponse{ + bool steeringSet = 1; +} + +message HeartbeatCheck{ + bool continue = 1; +} + +message HeartbeatCheckResponse{ + string errorMessage = 1; +} + +service CarControl{ + rpc SetThrottle(ThrottleRequest) returns (ThrottleResponse){} + rpc SetSteering(SteeringRequest) returns (SteeringResponse){} + rpc Heartbeat(stream HeartbeatCheck) returns (HeartbeatCheckResponse){} +} \ No newline at end of file