| @@ -1,12 +0,0 @@ | |||
| [[source]] | |||
| name = "pypi" | |||
| url = "https://pypi.org/simple" | |||
| verify_ssl = true | |||
| [dev-packages] | |||
| [packages] | |||
| pygame = "==1.9.4" | |||
| [requires] | |||
| python_version = "3.8" | |||
| @@ -1,51 +0,0 @@ | |||
| { | |||
| "_meta": { | |||
| "hash": { | |||
| "sha256": "66dc4fa611a558e59e4b96b5c720de3680644511017efcb95d30b2a242825bec" | |||
| }, | |||
| "pipfile-spec": 6, | |||
| "requires": { | |||
| "python_version": "3.8" | |||
| }, | |||
| "sources": [ | |||
| { | |||
| "name": "pypi", | |||
| "url": "https://pypi.org/simple", | |||
| "verify_ssl": true | |||
| } | |||
| ] | |||
| }, | |||
| "default": { | |||
| "pygame": { | |||
| "hashes": [ | |||
| "sha256:06dc92ccfea33b85f209db3d49f99a2a30c88fe9fb80fa2564cee443ece787b5", | |||
| "sha256:0919a2ec5fcb0d00518c2a5fa99858ccf22d7fbcc0e12818b317062d11386984", | |||
| "sha256:0a8c92e700e0042faefa998fa064616f330201890d6ea1c993eb3ff30ab53e99", | |||
| "sha256:220a1048ebb3d11a4d48cc4219ec8f65ca62fcafd255239478677625e8ead2e9", | |||
| "sha256:315861d2b8428f7b4d56d2c98d6c1acc18f08c77af4b129211bc036774f64be2", | |||
| "sha256:3469e87867832fe5226396626a8a6a9dac9b2e21a7819dd8cd96cf0e08bbcd41", | |||
| "sha256:54c19960180626165512d596235d75dc022d38844467cec769a8d8153fd66645", | |||
| "sha256:5ba598736ab9716f53dc943a659a9578f62acfe00c0c9c5490f3aca61d078f75", | |||
| "sha256:60ddc4f361babb30ff2d554132b1f3296490f3149d6c1c77682213563f59937a", | |||
| "sha256:6a49ab8616a9de534f1bf62c98beabf0e0bb0b6ff8917576bba22820bba3fdad", | |||
| "sha256:6d4966eeba652df2fd9a757b3fc5b29b578b47b58f991ad714471661ea2141cb", | |||
| "sha256:700d1781c999af25d11bfd1f3e158ebb660f72ebccb2040ecafe5069d0b2c0b6", | |||
| "sha256:73f4c28e894e76797b8ccaf6eb1205b433efdb803c70f489ebc3db6ac9c097e6", | |||
| "sha256:786eca2bea11abd924f3f67eb2483bcb22acff08f28dbdbf67130abe54b23797", | |||
| "sha256:7bcf586a1c51a735361ca03561979eea3180de45e6165bcdfa12878b752544af", | |||
| "sha256:82a1e93d82c1babceeb278c55012a9f5140e77665d372a6d97ec67786856d254", | |||
| "sha256:9e03589bc80a21ae951fca7659a767b7cac668289937e3756c0ab3d753cf6d24", | |||
| "sha256:aa8926a4e34fb0943abe1a8bb04a0ad82265341bf20064c0862db0a521100dfc", | |||
| "sha256:aa90689b889c417d2ac571ef2bbb5f7e735ae30c7553c60fae7508404f46c101", | |||
| "sha256:c9f8cdefee267a2e690bf17d61a8f5670b620f25a981f24781b034363a8eedc9", | |||
| "sha256:d9177afb2f46103bfc28a51fbc49ce18987a857e5c934db47b4a7030cb30fbd0", | |||
| "sha256:deb0551d4bbfb8131e2463a7fe1943bfcec5beb11acdf9c4bfa27fa5a9758d62", | |||
| "sha256:e7edfe57a5972aa9130ce9a186020a0f097e7a8e4c25e292109bdae1432b77f9", | |||
| "sha256:f0ad32efb9e26160645d62ba6cf3e5a5828dc4e82e8f41f9badfe7b685b07295" | |||
| ], | |||
| "index": "pypi", | |||
| "version": "==1.9.4" | |||
| } | |||
| }, | |||
| "develop": {} | |||
| } | |||
| @@ -35,7 +35,7 @@ class Iot_car(): | |||
| def __init__(self, testmode=True): | |||
| self.is_testmode_activated = testmode | |||
| if not testmode: | |||
| import servo_ctrl | |||
| from servo_ctrl import Motor, Steering | |||
| self.motor = Motor(1) | |||
| self.streeting = Steering(2) | |||
| @@ -84,28 +84,28 @@ class Iot_car(): | |||
| else: | |||
| self.speed_cruise_control = s | |||
| def def cruise_control_reset(self): | |||
| 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 is_testmode_activated: | |||
| 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 is_testmode_activated: | |||
| 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 is_testmode_activated: | |||
| if not self.is_testmode_activated: | |||
| self.__accelerate(0) | |||
| def reset_streeting(self): | |||
| @@ -1,257 +0,0 @@ | |||
| #!/usr/bin/env python2 | |||
| ####################################################################### | |||
| # Aufgabe 1 # | |||
| ####################################################################### | |||
| import pygame | |||
| import math | |||
| import argparse, sys | |||
| import servo_ctrl | |||
| width = 400 | |||
| height = 200 | |||
| freq = 50 # Sets the frequency of input procession | |||
| delta = 1.0 / freq # time per step | |||
| 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.) | |||
| speed_cur = 0 | |||
| angle_cur = 0 | |||
| V_MAX = 11 # Maximale Geswindigkeit 11 m/s | |||
| ANGLE_MAX = 45 | |||
| mouse_ctrl = False | |||
| v_step = True # Stufenweises regel der Beschlunigung in beide Richtungen | |||
| m_step = True | |||
| # vars for testmode | |||
| is_testmode_enabled = True | |||
| testmode_vars = {'is_servo_active': False} | |||
| # vars for car | |||
| motor = None | |||
| streeting = None | |||
| # start main pygame event processing loop here | |||
| pygame.display.init() | |||
| # set up the pygame screen enviroment | |||
| screen = pygame.display.set_mode((width, height)) | |||
| # get a clock to generate frequent behaviour | |||
| clock = pygame.time.Clock() | |||
| # States of the keys | |||
| keystates = { | |||
| 'quit': False, | |||
| 'accelerate': False, | |||
| 'decelerate': False, | |||
| 'reset': False, | |||
| 'accelerate_angle_right': False, | |||
| 'accelerate_angle_left': False, | |||
| 'acceleration_mouse': False, | |||
| 'mouse_ctrl': False, | |||
| } | |||
| running = True | |||
| # Functions for exercises | |||
| def calculate_acceleration(speed, acc): | |||
| 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): | |||
| # 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))))) | |||
| def toggle_mouse_ctrl(): | |||
| global mouse_ctrl | |||
| mouse_ctrl= not mouse_ctrl | |||
| def mouse_ctrl_calc_velocity(pos): | |||
| global height, V_MAX | |||
| x, y = pos | |||
| rel_y = y - (height/2) | |||
| return -1 * (rel_y / (height/2.0)) * V_MAX | |||
| def mouse_ctrl_calc_angle(pos): | |||
| global width, ANGLE_MAX | |||
| x, y = pos | |||
| rel_x = x - (width/2.0) | |||
| return (rel_x / (width/2)) * ANGLE_MAX | |||
| if __name__ == "__main__": | |||
| parser = argparse.ArgumentParser(description='IoT Lab script') | |||
| parser.add_argument('--notest', action='store_true', default=False) | |||
| args = parser.parse_args() | |||
| if not args.notest: | |||
| print "Running in testmode." | |||
| else: | |||
| is_testmode_enabled = False | |||
| motor = Motor(1) | |||
| streeting = Steering(2) | |||
| try: | |||
| while running: | |||
| # set clock frequency | |||
| clock.tick(freq); | |||
| # save the last speed 4 analysis | |||
| last = speed_cur | |||
| # process input events | |||
| for event in pygame.event.get(): | |||
| # exit on quit | |||
| if event.type == pygame.QUIT: | |||
| running = False | |||
| # check for key down events (press) | |||
| if event.type == pygame.KEYDOWN: | |||
| if event.key == pygame.K_q: | |||
| keystates['quit'] = True | |||
| elif event.key == pygame.K_w: | |||
| keystates['accelerate'] = True | |||
| elif event.key == pygame.K_s: | |||
| keystates['decelerate'] = True | |||
| elif event.key == pygame.K_d: | |||
| keystates['accelerate_angle_right'] = True | |||
| elif event.key == pygame.K_a: | |||
| keystates['accelerate_angle_left'] = True | |||
| elif event.key == pygame.K_m: | |||
| keystates['mouse_ctrl'] = True | |||
| elif event.key == pygame.K_r: | |||
| keystates['reset'] = True | |||
| # check for key up events (release) | |||
| if event.type == pygame.KEYUP: | |||
| if event.key == pygame.K_q: | |||
| keystates['quit'] = False | |||
| elif event.key == pygame.K_w: | |||
| v_step = True | |||
| testmode_vars['is_servo_active'] = False | |||
| keystates['accelerate'] = False | |||
| elif event.key == pygame.K_s: | |||
| v_step = True | |||
| testmode_vars['is_servo_active'] = False | |||
| keystates['decelerate'] = False | |||
| elif event.key == pygame.K_d: | |||
| keystates['accelerate_angle_right'] = False | |||
| elif event.key == pygame.K_a: | |||
| keystates['accelerate_angle_left'] = False | |||
| elif event.key == pygame.K_m: | |||
| keystates['mouse_ctrl'] = False | |||
| m_step = True | |||
| elif event.key == pygame.K_r: | |||
| v_step = True | |||
| keystates['reset'] = False | |||
| if event.type == pygame.MOUSEBUTTONDOWN: | |||
| # linke maustaste | |||
| if event.button == 1: | |||
| testmode_vars['is_servo_active'] = True | |||
| keystates['acceleration_mouse'] = True | |||
| if event.type == pygame.MOUSEBUTTONUP: | |||
| if event.button == 1: | |||
| testmode_vars['is_servo_active'] = False | |||
| keystates['acceleration_mouse'] = False | |||
| # do something about the key states here, now that the event queue has been processed | |||
| if keystates['quit']: | |||
| running = False | |||
| if keystates['reset']: | |||
| # reset | |||
| speed_cur = 0 | |||
| angle_cur = 0 | |||
| mouse_ctrl = False | |||
| if keystates['mouse_ctrl'] and m_step: | |||
| # beim umstellen zur maus steuerung und geschw. zuruecksetzen | |||
| speed_cur = 0 | |||
| angle_cur = 0 | |||
| toggle_mouse_ctrl() | |||
| m_step = False | |||
| print "Is mouse control enabled?: " + str(mouse_ctrl) | |||
| # Calculate valeues for control types | |||
| if mouse_ctrl: | |||
| pos = pygame.mouse.get_pos() | |||
| angle_cur = mouse_ctrl_calc_angle(pos) | |||
| if keystates['acceleration_mouse']: | |||
| speed_cur = mouse_ctrl_calc_velocity(pos) | |||
| elif not is_testmode_enabled: | |||
| speed_cur = 0 | |||
| else: | |||
| if keystates['accelerate']: # and v_step: | |||
| # Beschleunigen | |||
| v_step = False | |||
| if is_testmode_enabled: | |||
| calc_acc = calculate_acceleration(speed_cur, acc) | |||
| speed_cur = min(V_MAX, speed_cur + calc_acc) | |||
| testmode_vars['is_servo_active'] = True | |||
| else: | |||
| speed_cur = min(V_MAX, speed_cur + acc) | |||
| if keystates['decelerate']: # and v_step: | |||
| # abbremsen | |||
| v_step = False | |||
| if is_testmode_enabled: | |||
| calc_dec = calculate_acceleration(speed_cur, dec) | |||
| speed_cur = max(-1 * V_MAX, speed_cur - calc_dec) | |||
| testmode_vars['is_servo_active'] = True | |||
| else: | |||
| speed_cur = max(-1 * V_MAX, speed_cur - dec) | |||
| if keystates['accelerate_angle_right']: | |||
| # ist das so richtig angle_acc = 300? TODO | |||
| angle_cur = min(ANGLE_MAX, angle_cur + angle_acc) | |||
| if keystates['accelerate_angle_left']: | |||
| # ist das so richtig angle_acc = 300? TODO | |||
| angle_cur = max(-1 * ANGLE_MAX, angle_cur - angle_acc) | |||
| if not keystates['accelerate_angle_left'] and not keystates['accelerate_angle_right']: | |||
| angle_cur = 0 | |||
| if not is_testmode_enabled and (not keystates['accelerate'] and not keystates['decelerate']): | |||
| # Wenn nicht im testmode und weger beschl noch gebremst wird | |||
| speed_cur = 0 | |||
| if is_testmode_enabled: | |||
| if not testmode_vars['is_servo_active']: | |||
| speed_cur = min(0, speed_cur - calculate_friction(speed_cur, -1)) | |||
| else: | |||
| motor.set_speed(speed_cur) | |||
| steering.set_angle(angle_cur) | |||
| # Hier denn Wete an servos geben TODO | |||
| print("({},{} --> {})".format(speed_cur, angle_cur, (speed_cur - last) / delta)) + ", Servo_active: " + str(testmode_vars['is_servo_active']) | |||
| except KeyboardInterrupt: | |||
| print "Exiting through keyboard event (CTRL + C)" | |||
| # gracefully exit pygame here | |||
| pygame.quit() | |||
| @@ -1,11 +1,11 @@ | |||
| #!/usr/bin/env python | |||
| ####################################################################### | |||
| # Aufgabe 2 # | |||
| # Aufgabe 2 # | |||
| ####################################################################### | |||
| from linuxWiimoteLib import * | |||
| frim iot_car import Iot_car | |||
| from iot_car import Iot_car | |||
| # initialize wiimote | |||
| wiimote = Wiimote() | |||
| @@ -13,11 +13,13 @@ wiimote = Wiimote() | |||
| #Insert address and name of device here | |||
| # hcitool scan | |||
| # | |||
| device = ('', '') | |||
| # B8:AE:6E:30:0F:0F Nintendo RVL-CNT-01-TR | |||
| # | |||
| device = ('B8:AE:6E:30:0F:0F', 'Nintendo RVL-CNT-01-TR') | |||
| connected = False | |||
| car = Iot_car(testmode=True) | |||
| car = Iot_car(testmode=False) | |||
| # AUFGABE d | |||
| def set_led(remote): | |||
| @@ -30,32 +32,34 @@ def set_led(remote): | |||
| remote.SetLEDs(True, True, False, False) | |||
| elif p > 0.5 and p <= 0.75: | |||
| remote.SetLEDs(True, True, True, False) | |||
| else: | |||
| elif p == 1: | |||
| remote.SetLEDs(True, True, True, True) | |||
| else: | |||
| remote.SetLEDs(False, False, False, False) | |||
| try: | |||
| print "Press any key on wiimote to connect" | |||
| while (not connected): | |||
| connected = wiimote.Connect(device) | |||
| print "Press any key on wiimote to connect" | |||
| while (not connected): | |||
| connected = wiimote.Connect(device) | |||
| print "succesfully connected" | |||
| print "succesfully connected" | |||
| wiimote.SetAccelerometerMode() | |||
| wiistate = wiimote.WiimoteState | |||
| while True: | |||
| # re-calibrate accelerometer | |||
| if (wiistate.ButtonState.Home): | |||
| print 're-calibrating' | |||
| wiimote.calibrateAccelerometer() | |||
| sleep(0.1) | |||
| wiimote.SetAccelerometerMode() | |||
| wiistate = wiimote.WiimoteState | |||
| step = True | |||
| counter = 0 | |||
| print 'entering loop' | |||
| while True: | |||
| # re-calibrate accelerometer | |||
| if (wiistate.ButtonState.Home): | |||
| print 're-calibrating' | |||
| wiimote.calibrateAccelerometer() | |||
| sleep(0.1) | |||
| # Set acceleration and deceleration | |||
| if wiistate.ButtonState.One: | |||
| car.activate_cruise_control_forward() | |||
| else: | |||
| car.deactivate_cruise_control() | |||
| if wiistate.ButtonState.Two: | |||
| car.activate_cruise_control_forward() | |||
| elif wiistate.ButtonState.Two: | |||
| car.activate_cruise_control_backward() | |||
| else: | |||
| car.deactivate_cruise_control() | |||
| @@ -63,25 +67,38 @@ try: | |||
| # streeting | |||
| if wiistate.ButtonState.Up: | |||
| # streeting left | |||
| car.car.streeting_left() | |||
| car.streeting_left() | |||
| if wiistate.ButtonState.Down: | |||
| # streeting right | |||
| car.streeting_right() | |||
| if not wiistate.ButtonState.Down and not wiistate.ButtonState.Up: | |||
| car.reset_streeting() | |||
| if wiistate.ButtonState.Right and step: | |||
| car.cruise_control_increase() | |||
| step = False | |||
| if wiistate.ButtonState.Left and step: | |||
| car.cruise_control_decrease() | |||
| step = False | |||
| # reset button | |||
| if wiistate.ButtonState.Minus: | |||
| car.reset() | |||
| car.stop() | |||
| car.cruise_control_reset() | |||
| # set led states | |||
| set_led(wiimote) | |||
| counter = counter + 1 | |||
| if counter == 50: | |||
| step = True | |||
| counter = 0 | |||
| delta = 1.0 / 50 | |||
| print("({},{} --> {})".format(car.speed_cur, car.angle_cur, (car.speed_cur - car.speed_last) / delta)) + ", Servo_active: " + str(car.is_testmode_servo_active) + "CC Speed: " str(car.speed_cruise_control) | |||
| sleep(1 / 50) | |||
| print wiimote.getAccelState() | |||
| #print '({},{} --> {})'.format(car.speed_cur, car.angle_cur, (car.speed_cur - car.speed_last) / delta) + ", Servo_active: " + str(car.is_testmode_servo_active) + " CC Speed: " + str(car.speed_cruise_control) | |||
| sleep(0.01) | |||
| except KeyboardInterrupt: | |||
| print "Exiting through keyboard event (CTRL + C)" | |||
| exit(wiimote) | |||
| print "Exiting through keyboard event (CTRL + C)" | |||
| exit(wiimote) | |||
| @@ -8,6 +8,7 @@ if __name__ == "__main__": | |||
| parser.add_argument('-s', type=str, required=True, help='IPv4 address of the servers') | |||
| parser.add_argument('--tcp', action='store_true', help='Use TCP.') | |||
| parser.add_argument('--udp', action='store_true', help='Use UDP.') | |||
| parser.add_argument('--raspivid', defalt='-t 0 -fps 20 -w 1280 -h 720 -b 2000000 -o', help='Raspivid arguments.') | |||
| args = parser.parse_args() | |||
| if args.udp and args.tcp: | |||
| @@ -40,7 +41,7 @@ if __name__ == "__main__": | |||
| sock.connect((IP,PORT)) | |||
| # raspivid starten | |||
| cmd_raspivid = 'raspivid -t 0 -fps 20 -w 1280 -h 720 -b 2000000 -o -' | |||
| cmd_raspivid = 'raspivid ' + args.raspivid + ' -' | |||
| rasprocess = subprocess.Popen(cmd_raspivid,shell=True,stdout=subprocess.PIPE) | |||
| while True: | |||
| @@ -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) | |||
| '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) | |||
| 'stop' | |||
| car.accelerate(0) | |||
| sleep(0.1) | |||
| car.set_angle(-45) | |||
| sleep(0.1) | |||
| '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) | |||
| 'stop' | |||
| car.accelerate(0) | |||
| '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() | |||
| @@ -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 | |||
| @@ -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) | |||
| # coll.get_values_as_json() | |||
| #except KeyboardInterrupt: | |||
| # run = False | |||
| # exit(0) | |||
| #coll.stop() | |||
| GPIO.cleanup() | |||
| @@ -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> | |||
| @@ -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)) | |||
| @@ -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) | |||
| @@ -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) | |||
| @@ -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." | |||