Änderungen hinzugefügt. Sensoren waren kaputt, daher mussten wir Workarounds basteln.
This commit is contained in:
155
Versuchstag-4/autoparking.py
Executable file
155
Versuchstag-4/autoparking.py
Executable file
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/python
|
||||
from time import sleep
|
||||
|
||||
from iot_car import Iot_car
|
||||
from ikt_car_sensorik import Value_collector
|
||||
|
||||
car = Iot_car(testmode=False)
|
||||
vc = Value_collector()
|
||||
|
||||
def is_state_save(vc):
|
||||
return True
|
||||
distance_front = vc.ultrasonic_front.distance
|
||||
distance_back = vc.ultrasonic_back.distance
|
||||
if distance_front > 10 and distance_back > 10:
|
||||
return True
|
||||
return False
|
||||
|
||||
def stop(vc, car):
|
||||
print 'danger'
|
||||
car.set_angle(0)
|
||||
car.accelerate(0)
|
||||
vc.stop()
|
||||
exit(0)
|
||||
|
||||
def website_stop():
|
||||
car.set_angle(0)
|
||||
car.accelerate(0)
|
||||
vc.stop()
|
||||
|
||||
def park_lite():
|
||||
|
||||
car.set_angle(0)
|
||||
car.accelerate(0)
|
||||
try:
|
||||
bearing_start = vc.compass.bearing
|
||||
# steeling right
|
||||
car.set_angle(45)
|
||||
sleep(0.2)
|
||||
print
|
||||
'Backward'
|
||||
car.accelerate(-5)
|
||||
while is_state_save(vc) and not (vc.compass.bearing <= bearing_start - 45):
|
||||
sleep(0.1)
|
||||
if not is_state_save(vc):
|
||||
stop(vc, car)
|
||||
|
||||
print
|
||||
'stop'
|
||||
car.accelerate(0)
|
||||
sleep(0.1)
|
||||
car.set_angle(-45)
|
||||
sleep(0.1)
|
||||
print
|
||||
'Backward'
|
||||
car.accelerate(-5)
|
||||
while is_state_save(vc) and not (vc.compass.bearing >= bearing_start):
|
||||
sleep(0.1)
|
||||
if not is_state_save(vc):
|
||||
stop(vc, car)
|
||||
|
||||
print
|
||||
'stop'
|
||||
car.accelerate(0)
|
||||
print
|
||||
'end'
|
||||
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
vc.stop()
|
||||
exit(0)
|
||||
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
vc.stop()
|
||||
exit(0)
|
||||
|
||||
|
||||
|
||||
def park():
|
||||
car = Iot_car(testmode=False)
|
||||
vc = Value_collector()
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
|
||||
#angle_offset = -10
|
||||
|
||||
print 'Wait for Values'
|
||||
sleep(10)
|
||||
print 'Dist Front: ' + str(vc.ultrasonic_front.distance)
|
||||
print 'Dist Back: ' + str(vc.ultrasonic_back.distance)
|
||||
speed = 4
|
||||
|
||||
car.set_angle(0)
|
||||
car.accelerate(0)
|
||||
try:
|
||||
# drive forward an find gab
|
||||
print 'Forward'
|
||||
car.accelerate(0)
|
||||
while is_state_save(vc) and not vc.infrared.passed_gab:
|
||||
print vc.infrared.distance
|
||||
print vc.infrared.passed_gab
|
||||
|
||||
sleep(0.1)
|
||||
if not is_state_save(vc):
|
||||
stop(vc, car)
|
||||
|
||||
print 'stop'
|
||||
car.accelerate(0)
|
||||
bearing_start = vc.compass.bearing
|
||||
# steeling right
|
||||
car.set_angle(45)
|
||||
print 'Backward'
|
||||
car.accelerate(-5)
|
||||
while is_state_save(vc) and not (vc.compass.bearing <= bearing_start - 45):
|
||||
sleep(0.1)
|
||||
if not is_state_save(vc):
|
||||
stop(vc, car)
|
||||
|
||||
print 'stop'
|
||||
car.accelerate(0)
|
||||
|
||||
car.set_angle(-45)
|
||||
print 'Backward'
|
||||
car.accelerate(-5)
|
||||
while is_state_save(vc) and not (vc.compass.bearing >= bearing_start):
|
||||
sleep(0.1)
|
||||
if not is_state_save(vc):
|
||||
stop(vc, car)
|
||||
|
||||
print 'stop'
|
||||
car.accelerate(0)
|
||||
print 'end'
|
||||
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
vc.stop()
|
||||
exit(0)
|
||||
|
||||
car.accelerate(0)
|
||||
car.set_angle(0)
|
||||
vc.stop()
|
||||
exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
park()
|
||||
|
||||
|
||||
BIN
Versuchstag-4/autoparking.pyc
Normal file
BIN
Versuchstag-4/autoparking.pyc
Normal file
Binary file not shown.
32
Versuchstag-4/gpio_class.py
Normal file
32
Versuchstag-4/gpio_class.py
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
|
||||
def sb_write(fd, servo, pulse):
|
||||
try:
|
||||
os.write(fd, '%d=%d\n' % (servo,pulse))
|
||||
except IOError as e:
|
||||
print e
|
||||
|
||||
def write(servo, pulse):
|
||||
if servo == 1:
|
||||
if pulse < 100 or pulse > 200:
|
||||
print 'PWM %d out of range!' % (pulse)
|
||||
return
|
||||
|
||||
if servo == 2:
|
||||
if pulse < 100 or pulse > 200:
|
||||
print 'PWM %d out of range!' % (pulse)
|
||||
return
|
||||
|
||||
sb_write(fd, servo, pulse)
|
||||
|
||||
try:
|
||||
fd = os.open('/dev/servoblaster', os.O_WRONLY)
|
||||
except OSError as e:
|
||||
print 'could not open /dev/servoblaster'
|
||||
raise SystemExit(5)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
os.close(fd)
|
||||
pass
|
||||
|
||||
|
||||
BIN
Versuchstag-4/gpio_class.pyc
Normal file
BIN
Versuchstag-4/gpio_class.pyc
Normal file
Binary file not shown.
285
Versuchstag-4/ikt_car_sensorik.py
Normal file → Executable file
285
Versuchstag-4/ikt_car_sensorik.py
Normal file → Executable file
@@ -28,9 +28,10 @@ class Ultrasonic():
|
||||
#
|
||||
# Diese Methode soll ein Datenbyte an den Ultraschallsensor senden um eine Messung zu starten
|
||||
def write(self,value):
|
||||
try:
|
||||
bus.write_byte_data(self.address, 0x00, 0x51)
|
||||
except:
|
||||
try:
|
||||
bus.write_byte_data(self.address, 0x00, value)
|
||||
print 'ok'
|
||||
except:
|
||||
print "ERROR: Ultrasonic sensor start failed!"
|
||||
return 0
|
||||
|
||||
@@ -38,9 +39,13 @@ class Ultrasonic():
|
||||
#
|
||||
# Diese Methode soll den Lichtwert auslesen und zurueckgeben.
|
||||
def get_brightness(self):
|
||||
try:
|
||||
light_v = bus.read_byte_data(self.address, 0x01)
|
||||
except:
|
||||
light_v = 0
|
||||
try:
|
||||
#self.write(0x51)
|
||||
sleep(0.1)
|
||||
#light_v = bus.read_byte_data(self.address, 0x01)
|
||||
light_v = 100
|
||||
except:
|
||||
print "ERROR: Ultrasonic sensor get brightness failed!"
|
||||
return light_v
|
||||
|
||||
@@ -48,12 +53,15 @@ class Ultrasonic():
|
||||
#
|
||||
# Diese Methode soll die Entfernung auslesen und zurueckgeben.
|
||||
def get_distance(self):
|
||||
try:
|
||||
range_High_Byte = bus.read_byte_data(self.address, 0x02)
|
||||
range_Low_Byte = bus.read_byte_data(self.address, 0x03)
|
||||
dist = (range_High_Byte << 8) + range_Low_Byte
|
||||
except:
|
||||
print "ERROR: Ultrasonic sensor get distance failed!"
|
||||
dist = 0
|
||||
try:
|
||||
#self.write(0x51)
|
||||
sleep(0.07)
|
||||
#range_High_Byte = bus.read_byte_data(self.address, 0x02)
|
||||
#range_Low_Byte = bus.read_byte_data(self.address, 0x03)
|
||||
#dist = (range_High_Byte << 8) + range_Low_Byte
|
||||
except:
|
||||
print "ERROR: Ultrasonic sensor get distance failed!"
|
||||
return dist
|
||||
|
||||
def get_address(self):
|
||||
@@ -65,7 +73,7 @@ class UltrasonicThread(threading.Thread):
|
||||
stop = False
|
||||
|
||||
# distance to obstacle in cm
|
||||
distance = 0
|
||||
distance = 20
|
||||
|
||||
# brightness value
|
||||
brightness = 0
|
||||
@@ -74,23 +82,27 @@ class UltrasonicThread(threading.Thread):
|
||||
#
|
||||
# Hier muss der Thread initialisiert werden.
|
||||
def __init__(self, address):
|
||||
try:
|
||||
threading.Thread.__init__(self)
|
||||
time.sleep(0.1)
|
||||
self.ultrasonic = Ultrasonic(address)
|
||||
self.setDaemon(True)
|
||||
self.start()
|
||||
except:
|
||||
print "ERROR: Ultrasonic sensor thread init failed!"
|
||||
return 0
|
||||
threading.Thread.__init__(self)
|
||||
#try:
|
||||
threading.Thread.__init__(self)
|
||||
sleep(0.1)
|
||||
self.ultrasonic = Ultrasonic(address)
|
||||
self.stopped = False
|
||||
self.setDaemon(True)
|
||||
#self.start()
|
||||
#except:
|
||||
# print "ERROR: Ultrasonic sensor thread init failed!"
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Schreiben Sie die Messwerte in die lokalen Variablen
|
||||
def run(self):
|
||||
while not self.stopped:
|
||||
distance = self.ultrasonic.get_distance()
|
||||
brightness = self.ultrasonic.get_brightness()
|
||||
self.distance = self.ultrasonic.get_distance()
|
||||
self.brightness = self.ultrasonic.get_brightness()
|
||||
#print 'Ultrasonic: distance' + str(self.distance)
|
||||
#print 'Ultrasonic: brightness' + str(self.brightness)
|
||||
sleep(0.1)
|
||||
continue
|
||||
|
||||
def stop(self):
|
||||
@@ -112,8 +124,8 @@ class Compass(object):
|
||||
def get_bearing(self):
|
||||
b = 0
|
||||
try:
|
||||
bear1 = bus.read_byte_data(address, 2)
|
||||
bear2 = bus.read_byte_data(address, 3)
|
||||
bear1 = bus.read_byte_data(self.address, 2)
|
||||
bear2 = bus.read_byte_data(self.address, 3)
|
||||
bear = (bear1 << 8) + bear2
|
||||
b = bear/10.0
|
||||
except:
|
||||
@@ -126,17 +138,25 @@ class CompassThread(threading.Thread):
|
||||
# Compass bearing value
|
||||
bearing = 0
|
||||
|
||||
compass = None
|
||||
|
||||
stopped = False
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Hier muss der Thread initialisiert werden.
|
||||
def __init__(self, address):
|
||||
return 0
|
||||
threading.Thread.__init__(self)
|
||||
self.compass = Compass(address)
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Diese Methode soll den Kompasswert aktuell halten.
|
||||
def run(self):
|
||||
while not self.stopped:
|
||||
self.bearing = self.compass.get_bearing()
|
||||
#print 'Compass bearing: ' + str(self.bearing)
|
||||
sleep(0.1)
|
||||
continue
|
||||
|
||||
def stop(self):
|
||||
@@ -158,53 +178,128 @@ class Infrared(object):
|
||||
def get_voltage(self):
|
||||
voltage = 0
|
||||
try:
|
||||
voltage = bus.read_byte(self.address)
|
||||
voltage = 3.3 / 255.0 * bus.read_byte(self.address)
|
||||
except:
|
||||
print "Spannung konnte nicht ausgelesen werden!"
|
||||
return voltage
|
||||
return float(voltage)
|
||||
|
||||
# Aufgabe 3
|
||||
#
|
||||
# Der Spannungswert soll in einen Distanzwert umgerechnet werden.
|
||||
def get_distance(self):
|
||||
# v=(readChannel(0)/1023.0)*3.3
|
||||
v = self.get_voltage()
|
||||
# interpolation von https://tutorials-raspberrypi.de/wp-content/uploads/gp2y0a02yk-600x455.png
|
||||
dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
|
||||
if v > 0:
|
||||
dist = (1.0 / (v / 15.69)) - 0.42
|
||||
else:
|
||||
dist = 0
|
||||
return dist
|
||||
|
||||
class Windowed_values():
|
||||
|
||||
def __init__(self, size=100):
|
||||
self.size = size
|
||||
self.values = []
|
||||
|
||||
def add(self, value):
|
||||
if len(self.values) > self.size:
|
||||
self.values.pop(0)
|
||||
self.values.append(value)
|
||||
else:
|
||||
self.values.append(value)
|
||||
|
||||
def get_mean(self):
|
||||
return sum(self.values) / len(self.values)
|
||||
|
||||
def clear(self):
|
||||
self.values = []
|
||||
|
||||
class InfraredThread(threading.Thread):
|
||||
''' Thread-class for holding Infrared data '''
|
||||
|
||||
# distance to an obstacle in cm
|
||||
distance = 0
|
||||
last_distance = 0
|
||||
|
||||
# length of parking space in cm
|
||||
parking_space_length = 0
|
||||
parking_step = 0
|
||||
parking_length_start = 0
|
||||
parking_length_stop = 0
|
||||
|
||||
passed_gab = False
|
||||
|
||||
|
||||
gab_counter = 0
|
||||
|
||||
sensor = None
|
||||
stopped = False
|
||||
encoder = None
|
||||
step_count = 0
|
||||
|
||||
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Hier muss der Thread initialisiert werden.
|
||||
def __init__(self, address, encoder=None):
|
||||
return 0
|
||||
threading.Thread.__init__(self)
|
||||
self.sensor = Infrared(address)
|
||||
self.encoder = encoder
|
||||
|
||||
self.windowed_values = Windowed_values()
|
||||
self.curr_distance_values = Windowed_values(size=10)
|
||||
|
||||
def run(self):
|
||||
while not self.stopped:
|
||||
read_infrared_value()
|
||||
calculate_parking_space_length()
|
||||
tmp = self.distance
|
||||
self.distance = self.read_infrared_value()
|
||||
self.windowed_values.add(self.distance)
|
||||
self.curr_distance_values.add(self.distance)
|
||||
#self.parking_space_length = self.calculate_parking_space_length()
|
||||
self.last_distance = tmp
|
||||
|
||||
#print "Window: " + str(self.windowed_values.get_mean())
|
||||
#print "Value: " + str(self.curr_distance_values.get_mean())
|
||||
if abs(self.windowed_values.get_mean() - self.curr_distance_values.get_mean()) >= 10:
|
||||
if self.gab_counter == 1:
|
||||
self.passed_gab = True
|
||||
self.gab_counter = 0
|
||||
self.windowed_values.clear()
|
||||
self.curr_distance_values.clear()
|
||||
self.gab_counter = 1
|
||||
#print 'Infrared distance: ' + str(self.distance)
|
||||
#print 'Infraread parking: ' + str(self.parking_space_length)
|
||||
|
||||
sleep(0.1)
|
||||
|
||||
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Diese Methode soll den Infrarotwert aktuell halten
|
||||
def read_infrared_value(self):
|
||||
return 0
|
||||
def read_infrared_value(self):
|
||||
return self.sensor.get_distance()
|
||||
|
||||
# Aufgabe 5
|
||||
#
|
||||
# Hier soll die Berechnung der Laenge der Parkluecke definiert werden
|
||||
def calculate_parking_space_length(self):
|
||||
return 0
|
||||
length = self.parking_space_length
|
||||
if self.step_count > 5:
|
||||
self.step_count = 0
|
||||
if self.parking_step == 0 and self.distance > self.last_distance + 10:
|
||||
self.parking_step = 1
|
||||
self.parking_length_start = time()
|
||||
|
||||
if self.parking_step == 1 and self.distance + 10 < self.last_distance:
|
||||
self.parking_step = 0
|
||||
self.parking_length_stop = time()
|
||||
length = self.parking_length_stop - self.parking_length_start
|
||||
#self.passed_gab = True
|
||||
|
||||
|
||||
self.step_count = self.step_count + 1
|
||||
return length
|
||||
|
||||
def stop(self):
|
||||
self.stopped = True
|
||||
@@ -219,32 +314,32 @@ class Encoder(object):
|
||||
# Aufgabe 2
|
||||
#
|
||||
# Wieviel cm betraegt ein einzelner Encoder-Schritt?
|
||||
STEP_LENGTH = 0 # in cm !!!ONP: to measure the wheel!!!
|
||||
# Wheel is 6.5cm
|
||||
STEP_LENGTH = 1.27627# in cm !!!ONP: to measure the wheel!!!
|
||||
|
||||
# number of encoder steps
|
||||
counter = 0
|
||||
|
||||
def __init__(self, pin):
|
||||
self.pin = pin
|
||||
GPIO.add_event_detect(encoder_pin, GPIO.BOTH, callback=count, bouncetime=1)
|
||||
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
GPIO.remove_event_detect(pin)
|
||||
GPIO.add_event_detect(pin, GPIO.BOTH, callback=self.count, bouncetime=1)
|
||||
|
||||
# Aufgabe 2
|
||||
#
|
||||
# Jeder Flankenwechsel muss zur Berechnung der Entfernung gezaehlt werden.
|
||||
# Definieren Sie alle dazu noetigen Methoden.
|
||||
|
||||
def count(channel):
|
||||
global counter
|
||||
counter = counter + 1
|
||||
print "Number of impulses" + str(counter)
|
||||
def count(self, channel):
|
||||
self.counter = self.counter + 1
|
||||
#print "Number of impulses " + str(self.counter)
|
||||
|
||||
# Aufgabe 2
|
||||
#
|
||||
# Diese Methode soll die gesamte zurueckgelegte Distanz zurueckgeben.
|
||||
def get_travelled_dist(self):
|
||||
global counter
|
||||
global STEP_LENGTH
|
||||
dist = counter * STEP_LENGTH
|
||||
dist = self.counter * self.STEP_LENGTH
|
||||
return dist
|
||||
|
||||
class EncoderThread(threading.Thread):
|
||||
@@ -252,24 +347,40 @@ class EncoderThread(threading.Thread):
|
||||
|
||||
# current speed.
|
||||
speed = 0
|
||||
last_distance = 0
|
||||
|
||||
last_time = 0
|
||||
|
||||
# currently traversed distance.
|
||||
distance = 0
|
||||
|
||||
encoder = None
|
||||
|
||||
stopped = False
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Hier muss der Thread initialisiert werden.
|
||||
def __init__(self, encoder):
|
||||
try:
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(encoder_pin, GPIO.IN)
|
||||
except:
|
||||
print "ERROR: Encoder GPIO init failed!"
|
||||
return 0
|
||||
threading.Thread.__init__(self)
|
||||
self.encoder = encoder
|
||||
self.last_time = time()
|
||||
|
||||
def run(self):
|
||||
while not self.stopped:
|
||||
get_values()
|
||||
tmp = self.distance
|
||||
self.distance = self.encoder.get_travelled_dist()
|
||||
|
||||
time_curr = time()
|
||||
self.speed = (self.distance - self.last_distance) / (time_curr - self.last_time)
|
||||
self.last_time = time_curr
|
||||
|
||||
self.last_distance = tmp
|
||||
|
||||
#print 'Encoder traveled distance: ' + str(self.distance)
|
||||
|
||||
sleep(0.05)
|
||||
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
@@ -282,9 +393,42 @@ class EncoderThread(threading.Thread):
|
||||
def stop(self):
|
||||
self.stopped = True
|
||||
|
||||
|
||||
class Value_collector():
|
||||
|
||||
def __init__(self):
|
||||
e = Encoder(23)
|
||||
self.ultrasonic_front = UltrasonicThread(0x70)
|
||||
self.ultrasonic_front.start()
|
||||
self.ultrasonic_back = UltrasonicThread(0x71)
|
||||
self.ultrasonic_back.start()
|
||||
self.infrared = InfraredThread(0x4f, encoder=e)
|
||||
self.infrared.start()
|
||||
self.encoder = EncoderThread(e)
|
||||
self.encoder.start()
|
||||
self.compass = CompassThread(0x60)
|
||||
self.compass.start()
|
||||
|
||||
def get_values_as_json(self):
|
||||
return '{"speed":"' +str(self.encoder.speed) \
|
||||
+ '", "compass":"' + str(self.compass.bearing) \
|
||||
+ '", "dist0":"' + str(self.infrared.distance) \
|
||||
+ '", "dist1":"' + str(self.ultrasonic_front.distance) \
|
||||
+ '", "dist2":"' + str(self.ultrasonic_back.distance) \
|
||||
+ '", "travel":"' + str(self.encoder.distance) \
|
||||
+ '", "length":"' + str(self.infrared.parking_space_length) + '"}'
|
||||
|
||||
def stop(self):
|
||||
self.ultrasonic_front.stop()
|
||||
self.ultrasonic_back.stop()
|
||||
self.infrared.stop()
|
||||
self.encoder.stop()
|
||||
self.compass.stop()
|
||||
|
||||
|
||||
#################################################################################
|
||||
# Main Thread
|
||||
#################################################################################
|
||||
#################################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -308,3 +452,34 @@ if __name__ == "__main__":
|
||||
# Aufgabe 6
|
||||
#
|
||||
# Hier sollen saemtlichen Messwerte periodisch auf der Konsole ausgegeben werden.
|
||||
us_front = Ultrasonic(ultrasonic_front_i2c_address)
|
||||
us_back = Ultrasonic(ultrasonic_rear_i2c_address)
|
||||
c = Compass(compass_i2c_address)
|
||||
i = Infrared(infrared_i2c_address)
|
||||
e = Encoder(encoder_pin)
|
||||
|
||||
while True:
|
||||
print 'Ultrasonic Front distance: ' + str(us_front.get_distance()) + 'cm'
|
||||
print 'Ultrasonic Back distance: ' + str(us_back.get_distance()) + 'cm'
|
||||
print 'Compass bearing: ' + str(c.get_bearing()) + ' degree'
|
||||
print 'Infrared distance: ' + str(i.get_distance()) + 'cm'
|
||||
#print 'Traveled distance: ' + str(e.get_travelled_dist())
|
||||
sleep(1)
|
||||
print(chr(27) + '[2j')
|
||||
print('\033c')
|
||||
print('\x1bc')
|
||||
|
||||
#coll = Value_collector()
|
||||
#run = True
|
||||
#while run:
|
||||
#try:
|
||||
# print 'loop'
|
||||
# print coll.get_values_as_json()
|
||||
# sleep(5)
|
||||
# print
|
||||
# coll.get_values_as_json()
|
||||
#except KeyboardInterrupt:
|
||||
# run = False
|
||||
# exit(0)
|
||||
#coll.stop()
|
||||
GPIO.cleanup()
|
||||
|
||||
BIN
Versuchstag-4/ikt_car_sensorik.pyc
Normal file
BIN
Versuchstag-4/ikt_car_sensorik.pyc
Normal file
Binary file not shown.
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import tornado.httpserver
|
||||
import tornado.ioloop
|
||||
import tornado.options
|
||||
@@ -10,13 +9,28 @@ import json
|
||||
|
||||
import threading
|
||||
from ikt_car_sensorik import *
|
||||
import _servo_ctrl
|
||||
#import _servo_ctrl
|
||||
from math import acos, sqrt, degrees
|
||||
import os
|
||||
from autoparking import *
|
||||
|
||||
# Aufgabe 4
|
||||
#
|
||||
# Der Tornado Webserver soll die Datei index.html am Port 8081 zur Verfügung stellen
|
||||
|
||||
from tornado.options import define, options
|
||||
define("port", default=8081, help="run on the given port", type=int)
|
||||
|
||||
json_message = {}
|
||||
|
||||
parking = False
|
||||
stop = False
|
||||
|
||||
class IndexHandler(tornado.web.RequestHandler):
|
||||
@tornado.web.asynchronous
|
||||
def get(self):
|
||||
self.render("index.html")
|
||||
|
||||
# Aufgabe 3
|
||||
#
|
||||
# Der Tornado Webserver muss eine Liste der clients verwalten.
|
||||
@@ -26,39 +40,77 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||
print "hello WebSocketHandler"
|
||||
|
||||
def open(self):
|
||||
return 0
|
||||
print "new connection : {} ".format(self.request.remote_ip)
|
||||
clients.append(self)
|
||||
|
||||
def on_message(self, message):
|
||||
return 0
|
||||
global json_message
|
||||
global parking
|
||||
global stop
|
||||
print "message received {} ".format(message)
|
||||
|
||||
if message == 'stop_true':
|
||||
print "Stopping"
|
||||
stop = True
|
||||
elif message == 'park_true':
|
||||
print "Parking"
|
||||
parking = True
|
||||
else:
|
||||
pass
|
||||
|
||||
#json_message = {}
|
||||
#json_message["response"] = message
|
||||
# json_message = json.dumps(json_message)
|
||||
# json_message == {"response": message}
|
||||
|
||||
self.write_message(json_message)
|
||||
|
||||
def on_close(self):
|
||||
return 0
|
||||
print "connection closed"
|
||||
clients.remove(self)
|
||||
|
||||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
class DataThread(threading.Thread):
|
||||
'''Thread zum Senden der Zustandsdaten an alle Clients aus der Client-Liste'''
|
||||
|
||||
stop = False
|
||||
# Aufgabe 3
|
||||
#
|
||||
# Hier muss der Thread initialisiert werden.
|
||||
def __init__(self):
|
||||
return 0
|
||||
threading.Thread.__init__(self)
|
||||
self.setDaemon(True)
|
||||
self.start()
|
||||
self.stop = False
|
||||
print "OK: DataThread started!"
|
||||
|
||||
# Aufgabe 3
|
||||
#
|
||||
# Erstellen Sie hier Instanzen von Klassen aus dem ersten Teilversuch
|
||||
# Erstellen Sie hier Instanzen von Klassen aus dem ersten Teilversuch
|
||||
def set_sensorik(self, address_ultrasonic_front, address_ultrasonic_back, address_compass, address_infrared, encoder_pin):
|
||||
# nothing need to init for sensor here
|
||||
return 0
|
||||
|
||||
# Aufgabe 3
|
||||
#
|
||||
# Hier muessen die Sensorwerte ausgelesen und an alle Clients des Webservers verschickt werden.
|
||||
def run(self):
|
||||
while not self.stopped:
|
||||
continue
|
||||
global json_message
|
||||
print "OK: DataThread running!"
|
||||
getdata = Value_collector()
|
||||
while 1:
|
||||
try:
|
||||
#json_message = {"speed":"5", "compass":"120", "dist":"12", "length":"40"}
|
||||
json_message = getdata.get_values_as_json()
|
||||
sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
getdata.stop()
|
||||
#print "OK: DataSetted!"
|
||||
# get data here
|
||||
|
||||
def stop(self):
|
||||
self.stopped = True
|
||||
self.stop = True
|
||||
|
||||
class DrivingThread(threading.Thread):
|
||||
'''Thread zum Fahren des Autos'''
|
||||
@@ -66,18 +118,33 @@ class DrivingThread(threading.Thread):
|
||||
# Einparken
|
||||
#
|
||||
# Hier muss der Thread initialisiert werden.
|
||||
datatrd = DataThread()
|
||||
def __init__(self):
|
||||
return 0
|
||||
threading.Thread.__init__(self)
|
||||
self.setDaemon(True)
|
||||
self.start()
|
||||
self.stop = False
|
||||
print "OK: ParkingThread started!"
|
||||
|
||||
# Einparken
|
||||
#
|
||||
# Definieren Sie einen Thread, der auf die ueber den Webserver erhaltenen Befehle reagiert und den Einparkprozess durchfuehrt
|
||||
def run(self):
|
||||
while not self.stopped:
|
||||
continue
|
||||
global parking
|
||||
global stop
|
||||
parklock = False
|
||||
while 1:
|
||||
if parking == True and not parklock:
|
||||
park_lite()
|
||||
print "OK: Parking started!"
|
||||
parklock = True
|
||||
if stop == True:
|
||||
website_stop()
|
||||
print "OK: Stop!"
|
||||
|
||||
|
||||
def stop(self):
|
||||
self.stopped = True
|
||||
self.stop = True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -86,6 +153,20 @@ if __name__ == "__main__":
|
||||
#
|
||||
# Erstellen und starten Sie hier eine Instanz des DataThread und starten Sie den Webserver .
|
||||
|
||||
datatrd = DataThread()
|
||||
parktrd = DrivingThread()
|
||||
|
||||
clients = []
|
||||
# Websocket Server initialization
|
||||
tornado.options.parse_command_line()
|
||||
app = tornado.web.Application(handlers=[(r"/ws", WebSocketHandler), (r"/", IndexHandler), (r'/(.*)', tornado.web.StaticFileHandler, {'path': os.path.dirname(__file__)}),])
|
||||
httpServer = tornado.httpserver.HTTPServer(app)
|
||||
httpServer.listen(options.port)
|
||||
print "Listening on port : ", options.port
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
|
||||
|
||||
#data.start()
|
||||
|
||||
# Einparken
|
||||
#
|
||||
|
||||
@@ -30,9 +30,45 @@
|
||||
|
||||
<script type="text/javascript" src="smoothie.js"></script>
|
||||
|
||||
Parking control: <button id="btn_start">Start</button>
|
||||
|
||||
<button id="btn_stop">Stop</button>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Aufgabe 4-->
|
||||
<!--Für jeden Datensatz muss eine Zeichenfläche 'canvas' definiert werden-->
|
||||
|
||||
<table border="1">
|
||||
|
||||
<tr>
|
||||
<td>Geschwindigkeit:<br>
|
||||
<canvas class="canvas" id="speed" width="400" height="150"></canvas><br></td>
|
||||
<td>Himmelrichtung:<br>
|
||||
<canvas class="canvas" id="compass" width="400" height="150"></canvas><br></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Abstand vom Auto zum Hindernis:<br></td>
|
||||
<td>IR:<br>
|
||||
<canvas class="canvas" id="dist0" width="400" height="150"></canvas><br></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Front:<br>
|
||||
<canvas class="canvas" id="dist1" width="400" height="150"></canvas><br></td>
|
||||
<td>Rear:<br>
|
||||
<canvas class="canvas" id="dist2" width="400" height="150"></canvas><br></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Länge der Parklücke:<br>
|
||||
<canvas class="canvas" id="length" width="400" height="150"></canvas><br></td>
|
||||
<td>Encoder Traveled distance:<br>
|
||||
<canvas class="canvas" id="travel" width="400" height="150"></canvas><br></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<!--Einparken -->
|
||||
<!--Es müssen Knöpfe zum Starten und Stoppen des Parkvorgangs definiert werden-->
|
||||
@@ -41,16 +77,45 @@
|
||||
// Aufgabe 4
|
||||
//
|
||||
// Damit die Daten dargestellt werden können muss ein Websocket geöffnet werden, der bei jeder neuen Nachricht die Daten aus dieser Nachricht rausholt und visualisiert.
|
||||
var dataSocket = ;
|
||||
var dataSocket = new WebSocket("ws://192.168.1.42:8081/ws");
|
||||
// THE IP NEED TO BE CHANGED!
|
||||
|
||||
var reply = 'nop';
|
||||
|
||||
document.getElementById("btn_stop").addEventListener('click',
|
||||
()=>{
|
||||
reply = 'stop_true';
|
||||
dataSocket.send(reply);
|
||||
console.log("ParkCtrl: Stopping");
|
||||
});
|
||||
|
||||
document.getElementById("btn_start").addEventListener('click',
|
||||
()=>{
|
||||
reply = 'park_true';
|
||||
dataSocket.send(reply);
|
||||
console.log("ParkCtrl: Parking");
|
||||
});
|
||||
|
||||
dataSocket.onopen = function(){
|
||||
console.log("connected");
|
||||
};
|
||||
console.log("connected");
|
||||
dataSocket.send('connection established')
|
||||
};
|
||||
|
||||
dataSocket.onmessage = function(evt) {
|
||||
// Aufgabe 4
|
||||
// Die empfangenen Daten müssen an die Charts weitergegeben werden.
|
||||
// evt.data == {"speed":"value", "compass":"value", "dist":"value", "length":"value"}
|
||||
console.log(evt.data);
|
||||
dataSocket.send(reply);
|
||||
var msg = JSON.parse(evt.data);
|
||||
|
||||
speed.append(new Date().getTime(), parseFloat(msg.speed));
|
||||
compass.append(new Date().getTime(), parseFloat(msg.compass));
|
||||
dist0.append(new Date().getTime(), parseFloat(msg.dist0));
|
||||
dist1.append(new Date().getTime(), parseFloat(msg.dist1));
|
||||
dist2.append(new Date().getTime(), parseFloat(msg.dist2));
|
||||
length.append(new Date().getTime(), parseFloat(msg.length));
|
||||
travel.append(new Date().getTime(), parseFloat(msg.travel));
|
||||
};
|
||||
|
||||
dataSocket.onclose = function(evt) {
|
||||
@@ -61,6 +126,49 @@
|
||||
// Aufgabe 4
|
||||
//
|
||||
// Für jeden Datensatz muss ein eine SmoothieChart in einem vorher definierten canvas-Element erstellt werden.
|
||||
var speedChart = new SmoothieChart({ minValue: 0, maxValue: 15, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var speed = new TimeSeries();
|
||||
speedChart.addTimeSeries(speed);
|
||||
speedChart.streamTo(document.getElementById("speed"), 100);
|
||||
|
||||
var compassChart = new SmoothieChart({ minValue: 0, maxValue: 360, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var compass = new TimeSeries();
|
||||
compassChart.addTimeSeries(compass);
|
||||
compassChart.streamTo(document.getElementById("compass"), 100);
|
||||
|
||||
var dist0Chart = new SmoothieChart({ minValue: 0, maxValue: 100, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var dist0 = new TimeSeries();
|
||||
dist0Chart.addTimeSeries(dist0);
|
||||
dist0Chart.streamTo(document.getElementById("dist0"), 100);
|
||||
|
||||
var dist1Chart = new SmoothieChart({ minValue: 0, maxValue: 100, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var dist1 = new TimeSeries();
|
||||
dist1Chart.addTimeSeries(dist1);
|
||||
dist1Chart.streamTo(document.getElementById("dist1"), 100);
|
||||
|
||||
var dist2Chart = new SmoothieChart({ minValue: 0, maxValue: 100, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var dist2 = new TimeSeries();
|
||||
dist2Chart.addTimeSeries(dist2);
|
||||
dist2Chart.streamTo(document.getElementById("dist2"), 100);
|
||||
|
||||
var lengthChart = new SmoothieChart({ minValue: 0, maxValue: 300, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var length = new TimeSeries();
|
||||
lengthChart.addTimeSeries(length);
|
||||
lengthChart.streamTo(document.getElementById("length"), 100);
|
||||
|
||||
var travelChart = new SmoothieChart({ minValue: 0, maxValue: 500, grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 500, verticalSections: 6 } });
|
||||
|
||||
var travel = new TimeSeries();
|
||||
travelChart.addTimeSeries(length);
|
||||
travelChart.streamTo(document.getElementById("travel"), 100);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
143
Versuchstag-4/iot_car.py
Normal file
143
Versuchstag-4/iot_car.py
Normal file
@@ -0,0 +1,143 @@
|
||||
import math
|
||||
|
||||
def calculate_acceleration(speed, acc, V_MAX=11):
|
||||
sigma = 2.5
|
||||
mu = V_MAX / 2
|
||||
return acc * (1 - 0.5 * (1 + (math.erf((abs(speed) - mu) / (math.sqrt(2 * sigma**2))))))
|
||||
|
||||
def calculate_friction(speed, f, V_MAX=11):
|
||||
# TODO hier stimmt was nicht
|
||||
sigma = 4
|
||||
mu = V_MAX / 2
|
||||
return (f/2) * (1 + (math.erf((abs(speed) - mu) / (math.sqrt(2 * sigma**2)))))
|
||||
|
||||
class Iot_car():
|
||||
|
||||
V_MAX = 11 #m/s
|
||||
A_MAX = 45 # degree
|
||||
|
||||
acc = 2.6 # Max acceleration of the car (per sec.)
|
||||
dec = 4.5 # Max deceleration of the car (per sec.)
|
||||
frict = -1 # max friction
|
||||
angle_acc = 300 # max change of angle (per sec.)
|
||||
|
||||
is_testmode_activated = True
|
||||
is_testmode_servo_active = False
|
||||
|
||||
speed_cur = 0
|
||||
speed_last = 0
|
||||
angle_cur = 0
|
||||
speed_cruise_control = 0 # m/s but only positive
|
||||
|
||||
motor = None
|
||||
streeting = None
|
||||
|
||||
def __init__(self, testmode=True):
|
||||
self.is_testmode_activated = testmode
|
||||
if not testmode:
|
||||
from servo_ctrl import Motor, Steering
|
||||
self.motor = Motor(1)
|
||||
self.streeting = Steering(2)
|
||||
|
||||
# for keyboard control
|
||||
def __testmode_accelerate(self):
|
||||
calc_acc = calculate_acceleration(self.speed_cur, self.acc)
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = min(self.V_MAX, self.speed_cur + calc_acc)
|
||||
self.is_testmode_servo_active = True
|
||||
|
||||
def __testmode_decelerate(self):
|
||||
calc_dec = calculate_acceleration(self.speed_cur, self.dec)
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = max(-1 * self.V_MAX, self.speed_cur - calc_dec)
|
||||
self.is_testmode_servo_active = True
|
||||
|
||||
def __accelerate(self, speed):
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = speed
|
||||
self.motor.set_speed(speed)
|
||||
|
||||
def accelerate(self, speed=0, direct=False):
|
||||
if direct and self.is_testmode_activated: # Mouse testmode
|
||||
self.last = self.speed_cur
|
||||
self.speed_cur = speed
|
||||
elif self.is_testmode_activated:
|
||||
if speed > 0:
|
||||
self.__testmode_accelerate()
|
||||
elif speed < 0:
|
||||
self.__testmode_decelerate()
|
||||
else:
|
||||
self.__accelerate(speed)
|
||||
|
||||
# for wii remote
|
||||
def cruise_control_increase(self):
|
||||
s = min(self.V_MAX, self.speed_cruise_control + 2.75)
|
||||
if s < 0:
|
||||
self.speed_cruise_control = 0
|
||||
else:
|
||||
self.speed_cruise_control = s
|
||||
|
||||
def cruise_control_decrease(self):
|
||||
s = min(self.V_MAX, self.speed_cruise_control - 2.75)
|
||||
if s < 0:
|
||||
self.speed_cruise_control = 0
|
||||
else:
|
||||
self.speed_cruise_control = s
|
||||
|
||||
def cruise_control_reset(self):
|
||||
self.speed_cruise_control = 0
|
||||
|
||||
def activate_cruise_control_forward(self):
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = self.speed_cruise_control
|
||||
self.is_testmode_servo_active = True
|
||||
if not self.is_testmode_activated:
|
||||
self.__accelerate(self.speed_cruise_control)
|
||||
|
||||
def activate_cruise_control_backward(self):
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = -1 * self.speed_cruise_control
|
||||
self.is_testmode_servo_active = True
|
||||
if not self.is_testmode_activated:
|
||||
self.__accelerate(-1 * self.speed_cruise_control)
|
||||
|
||||
def deactivate_cruise_control(self):
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = 0
|
||||
self.is_testmode_servo_active = False
|
||||
if not self.is_testmode_activated:
|
||||
self.__accelerate(0)
|
||||
|
||||
def reset_streeting(self):
|
||||
self.set_angle(0)
|
||||
|
||||
def streeting_right(self, angle=0):
|
||||
if angle > 0:
|
||||
a = angle
|
||||
else:
|
||||
a = min(self.A_MAX, self.angle_cur + self.angle_acc)
|
||||
self.set_angle(a)
|
||||
|
||||
def streeting_left(self, angle=0):
|
||||
if angle < 0:
|
||||
a = angle
|
||||
else:
|
||||
a = max(-1 * self.A_MAX, self.angle_cur - self.angle_acc)
|
||||
self.set_angle(a)
|
||||
|
||||
def set_angle(self, angle):
|
||||
self.angle_cur = angle
|
||||
if not self.is_testmode_activated:
|
||||
self.streeting.set_angle(angle)
|
||||
|
||||
def stop(self):
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = 0
|
||||
self.angle_cur = 0
|
||||
|
||||
def symulate(self):
|
||||
if self.is_testmode_activated:
|
||||
if not self.is_testmode_servo_active:
|
||||
self.speed_last = self.speed_cur
|
||||
self.speed_cur = min(0, self.speed_cur - calculate_friction(self.speed_cur, self.frict))
|
||||
|
||||
BIN
Versuchstag-4/iot_car.pyc
Normal file
BIN
Versuchstag-4/iot_car.pyc
Normal file
Binary file not shown.
42
Versuchstag-4/sensor_test.py
Executable file
42
Versuchstag-4/sensor_test.py
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#from smbus import SMBus
|
||||
import smbus
|
||||
import time
|
||||
|
||||
bus = smbus.SMBus(1) # 1 indicates /dev/i2c-1
|
||||
|
||||
address_SRF_v = 0x70 # Addresse vorderer Ultraschallsensor
|
||||
address_SRF_h = 0x71 # Addresse hinterer Ultraschallsensor
|
||||
|
||||
#Messung starten und Messwert in cm
|
||||
bus.write_byte_data(address_SRF_v, 0x00, 0x51)
|
||||
bus.write_byte_data(address_SRF_h, 0x00, 0x51)
|
||||
|
||||
#Wartezeit von 70 ms
|
||||
time.sleep(0.07)
|
||||
# Messwert abholen (vorderer Ultraschallsensor)
|
||||
range_High_Byte = bus.read_byte_data(address_SRF_v, 0x02) #hoeherwertiges Byte
|
||||
range_Low_Byte = bus.read_byte_data(address_SRF_v, 0x03) #niederwertiges Byte
|
||||
# Lichtwert abholen (vorderer Ultraschallsensor)
|
||||
light_v = bus.read_byte_data(address_SRF_v, 0x01)
|
||||
|
||||
print(range_High_Byte)
|
||||
print(range_Low_Byte)
|
||||
print(light_v)
|
||||
|
||||
#Address Infrarot
|
||||
address_IR = 0x4f
|
||||
#Messwert Abholen
|
||||
distance_IR = bus.read_byte(address_IR)
|
||||
|
||||
print('infrared ' + str(distance_IR))
|
||||
|
||||
#Address Kompass
|
||||
address_COM = 0x60
|
||||
#Messwert abholen
|
||||
bear_High_Byte = bus.read_byte_data(address_COM, 2) #hoeherwertiges Byte
|
||||
bear_Low_Byte = bus.read_byte_data(address_COM, 3) #niederwertiges Byte
|
||||
|
||||
print(bear_High_Byte)
|
||||
print(bear_Low_Byte)
|
||||
62
Versuchstag-4/servo_ctrl.py
Normal file
62
Versuchstag-4/servo_ctrl.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#######################################################################
|
||||
# Aufgabe 1.3 #
|
||||
#######################################################################
|
||||
|
||||
import gpio_class
|
||||
|
||||
def write(servo, pulse):
|
||||
gpio_class.write(servo, pulse)
|
||||
|
||||
class Motor(object):
|
||||
|
||||
PWM_PIN = 1 # GPIO pin 11
|
||||
min_pulse = 100 #ms -> -11 m/s
|
||||
max_pulse = 200 #ms -> 11 m/s
|
||||
servo = None
|
||||
__is_active = False
|
||||
v_max = 11.0
|
||||
|
||||
|
||||
def __init__(self, servo):
|
||||
self.servo = servo
|
||||
|
||||
def set_speed(self, speed):
|
||||
if abs(speed) > self.v_max:
|
||||
speed = self.v_max
|
||||
if speed == 0:
|
||||
self.__is_active = False
|
||||
else:
|
||||
self.__is_active = True
|
||||
|
||||
pulse = 150 + ((speed / self.v_max) * ((self.max_pulse - self.min_pulse)/2))
|
||||
write(self.servo, pulse)
|
||||
|
||||
def stop(self):
|
||||
self.set_speed(0)
|
||||
|
||||
# Aufgabe 1d
|
||||
def is_active(self):
|
||||
return self.__is_active
|
||||
|
||||
class Steering(object):
|
||||
|
||||
PWM_PIN = 2 # GPIO pin 12
|
||||
min_pulse = 115 # -45
|
||||
max_pulse = 195 # 45
|
||||
servo = None
|
||||
angle_max = 45
|
||||
|
||||
def __init__(self, servo):
|
||||
self.servo = servo
|
||||
|
||||
def set_angle(self, angle):
|
||||
if abs(angle) > self.angle_max:
|
||||
angle = self.angle_max
|
||||
|
||||
pulse = 155 + ((angle / self.angle_max) * ((self.max_pulse - self.min_pulse)/2))
|
||||
write(self.servo, pulse)
|
||||
|
||||
def stop(self):
|
||||
self.set_angel(0)
|
||||
BIN
Versuchstag-4/servo_ctrl.pyc
Normal file
BIN
Versuchstag-4/servo_ctrl.pyc
Normal file
Binary file not shown.
21
Versuchstag-4/set_value.py
Normal file
21
Versuchstag-4/set_value.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
from iot_car import Iot_car
|
||||
import argparse
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Set pwm value for testing. Aufgabe 4d')
|
||||
parser.add_argument('--motor', action='store_true', default=False)
|
||||
parser.add_argument('--steering', action='store_true', default=False)
|
||||
parser.add_argument('-v', '--value', required=True)
|
||||
args = parser.parse_args()
|
||||
car = Iot_car(testmode=False)
|
||||
if args.motor and args.steering:
|
||||
print "Wrong usage! Can not set both."
|
||||
exit(1)
|
||||
elif args.motor:
|
||||
car.accelerate(float(args.value))
|
||||
elif args.steering:
|
||||
car.set_angle(float(args.value))
|
||||
else:
|
||||
print "Something went wrong."
|
||||
Reference in New Issue
Block a user