Add 'car/' from commit 'eee0e8dc445691e600680f4abc77f2814b20b054'

git-subtree-dir: car
git-subtree-mainline: 1d29a5526c
git-subtree-split: eee0e8dc44
This commit is contained in:
Piv
2020-04-19 11:07:44 +09:30
93 changed files with 8401 additions and 0 deletions

View 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
car/control/__init__.py Normal file
View File

View File

View File

@@ -0,0 +1,42 @@
# A dummy vehicle class to use when
class MockVehicle:
def __init__(self, motor_pin=19, servo_pin=18):
self.motor_pin = motor_pin
self.steering_pin = servo_pin
@property
def throttle(self):
return self._throttle
@throttle.setter
def throttle(self, value):
self._throttle = value
@property
def steering(self):
return self._steering
@steering.setter
def steering(self, value):
self._steering = value
@property
def motor_pin(self):
return self._motor_pin
@motor_pin.setter
def motor_pin(self, value):
self._motor_pin = value
@property
def steering_pin(self):
return self._steering_pin
@steering_pin.setter
def steering_pin(self, value):
self._steering_pin = value
def stop(self):
self.throttle = 0

View File

@@ -0,0 +1,83 @@
from gpiozero import Servo, Device
from gpiozero.pins.pigpio import PiGPIOFactory
import subprocess
def _safely_set_servo_value(servo, value):
try:
if value < -1 or value > 1:
print("Not setting throttle, invalid value set.")
return False
servo.value = value
except TypeError:
print("throttle should be a number, preferably a float.")
return False
return True
def _is_pin_valid(pin):
if isinstance(pin, int):
if pin < 2 or pin > 21:
print("Invalid GPIO pin")
return False
return True
else:
print("Value must be an int.")
return False
# TODO: Allow a vector to be set to change the throttle/steering, for vehicles that don't use
# two servos for controls (e.g. drone, dog)
class Vehicle:
def __init__(self, motor_pin=19, servo_pin=18):
subprocess.call(['sudo', 'pigpiod'])
Device.pin_factory = PiGPIOFactory()
print('Using pin factory:')
print(Device.pin_factory)
self.motor_pin = motor_pin
self.steering_pin = servo_pin
self.initialise_motor()
def initialise_motor(self):
self._motor_servo = Servo(
self._motor_pin, pin_factory=Device.pin_factory)
self._steering_servo = Servo(self._steering_pin, pin_factory=Device.pin_factory)
@property
def throttle(self):
return self._motor_servo.value
@throttle.setter
def throttle(self, value):
_safely_set_servo_value(self._motor_servo, value)
@property
def steering(self):
return self._motor_servo.value
@steering.setter
def steering(self, value):
_safely_set_servo_value(self._motor_servo, value)
@property
def motor_pin(self):
return self._motor_pin
@motor_pin.setter
def motor_pin(self, value):
# TODO: Reinitialise the servo when the pin changes, or discard this method
# (probably don't want to allow pin changes whilst the device is in use anyway)
self._motor_pin = value if _is_pin_valid(value) else self._motor_pin
@property
def steering_pin(self):
return self._steering_pin
@steering_pin.setter
def steering_pin(self, value):
self._steering_pin = value if _is_pin_valid(value) else self._steering_pin
def stop(self):
self.throttle = 0
self.steering = 0
def change_with_vector(self, vector):
pass

View File

@@ -0,0 +1,40 @@
from threading import Timer, Thread
from concurrent import futures
import time
import control.motorService_pb2 as motorService_pb2
import control.motorService_pb2_grpc as motorService_pb2_grpc
class MotorServicer(motorService_pb2_grpc.CarControlServicer):
def __init__(self, vehicle):
self.vehicle = vehicle
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.
print('Setting throttle to: ' + str(request.throttle))
self.set_timeout(3)
self.vehicle.throttle = request.throttle
return motorService_pb2.ThrottleResponse(throttleSet=True)
def SetSteering(self, request, context):
print('Setting steering to: ' + str(request.steering))
self.vehicle.steering = 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.vehicle.stop()