Änderungen hinzugefügt. Sensoren waren kaputt, daher mussten wir Workarounds basteln.

This commit is contained in:
2020-09-18 09:36:30 +02:00
parent 1ac1c40332
commit 3746a32b31
24 changed files with 945 additions and 428 deletions

155
Versuchstag-4/autoparking.py Executable file
View 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()

Binary file not shown.

View 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

Binary file not shown.

285
Versuchstag-4/ikt_car_sensorik.py Normal file → Executable file
View 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()

Binary file not shown.

View File

@@ -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
#

View File

@@ -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
View 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

Binary file not shown.

42
Versuchstag-4/sensor_test.py Executable file
View 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)

View 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)

Binary file not shown.

View 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."